【问题标题】:NHibernate with string primary key and relationshipsNHibernate 与字符串主键和关系
【发布时间】:2009-01-04 22:41:26
【问题描述】:

我刚刚被这个问题困扰了一个小时,最终我很烦人地发现了这个问题。

情况

我有一个表,它使用一个字符串作为主键,这个表有各种多对一和多对多关系,都在这个主键之外。

从表中搜索多个项目时,所有关系都被带回。但是,每当我尝试通过主键(字符串)获取对象时,它并没有带回任何关系,它们总是设置为 0。

部分解决方案

所以我查看了我的日志以查看 SQL 正在做什么以及返回正确的结果。所以我以各种随机的方式尝试了各种事情,最终得出了结论。传递给 get 方法的字符串的情况与数据库中的情况并不完全相同,因此当它尝试将关系项与主实体匹配时,它什么也没找到(或者至少是 NHIbernate不是因为正如我上面所说的 SQL 实际上返回了正确的结果)

真正的解决方案

还有其他人遇到过这个吗?如果是这样,您如何告诉 NHibernate 在将 SQL 结果与实体匹配时忽略大小写?这很愚蠢,因为它以前工作得很好,现在突然开始注意字符串的大小写了。

【问题讨论】:

  • 你能发布你的映射文件吗?
  • 新添加的项目的大小写是否正确?你最近更新了 NHibernate 吗? SQL 通常是区分大小写的,但是使用“LIKE”语句它们都可以取决于方言,但是在解析关系时你不想使用它。

标签: .net nhibernate nhibernate-mapping


【解决方案1】:

我在我的数据库中的 ref 表上有完全相同的情况。我以与您相同的方式映射架构文件​​。在代码中,当我通过主键查询记录时,我使用 NHibernate ISession 的实例执行以下操作:

return session.Get<T>(id);

在此语句中,T 是您要查询的类型,id 是您要查找的字符串 id(主键)

这是我的映射文件的示例:

    <class name="Merchant" table="T__MERCHANT">
        <id name="MerchantId" column="MERCHANT_ID" type="string">
            <generator class="assigned" />
        </id>

        <property name="MerchantStatusId" column="MERCHANT_STATUS_ID" type="Char" not-null="true" length="1" />
        <property name="MerchantStatusName" column="MERCHANT_STATUS_NAME" type="string" length="50" />
        <property name="MerchantName" column="NAME" type="string" not-null="true" length="50" />
 </class>
</hibernate-mapping>

我的 C# 代码如下所示:

public Merchant GetMerchantById(string id)
{
     return session.Get<Merchant>(id);
}

【讨论】:

    【解决方案2】:

    为了保持一致,请修改:

    <joined-subclass name="JohnHarmanLtd.Web.FineArtCompany.Models.Book, App_Code.tqeub3fb, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
    

    更具体地说是“App_Code.tqeub3fb”。看起来您正在使用来自 ASP.NET 网站的临时程序集作为 NHibernate 映射的一部分?

    将您的业务实体移到它们自己的库中,这样程序集名称始终相同。

    【讨论】:

      【解决方案3】:

      这是我的解决方法(这是一种解决方法;我正在处理 IMO 设计不佳的就地数据库)。

      原文出自:https://forum.hibernate.org/viewtopic.php?f=25&t=979685&view=previous

      这是我的自定义字符串类(在 VB 中):

      Imports NHibernate.UserTypes
      Imports NHibernate.Type
      Imports NHibernate.SqlTypes
      
      Public Class CaseInsensitiveStringType
          Inherits AbstractStringType
      
          ' Methods
          Public Sub New()
              MyBase.New(New StringSqlType)
          End Sub
      
          Public Sub New(ByVal sqlType As StringSqlType)
              MyBase.New(sqlType)
          End Sub
      
      
          ' Properties
          Public Overrides ReadOnly Property Name As String
              Get
                  Return "InsensitiveString"
              End Get
          End Property
      
          Public Overrides Function IsEqual(ByVal x As Object, ByVal y As Object) As Boolean
              Return MyBase.IsEqual(x, y) OrElse (x IsNot Nothing AndAlso y IsNot Nothing AndAlso String.Equals(x, y, StringComparison.InvariantCultureIgnoreCase))
          End Function
      
          Public Overrides Function GetHashCode(ByVal x As Object, ByVal entityMode As NHibernate.EntityMode, ByVal factory As NHibernate.Engine.ISessionFactoryImplementor) As Integer
              Return MyBase.GetHashCode(x.ToString().Trim().ToUpperInvariant(), entityMode, factory)
          End Function
      End Class
      

      而且我使用 FluentNhibernate,所以这是映射的样子(仅适用于 Id 字段):

      Id(Function(x) x.Id).GeneratedBy.Assigned().CustomType(Of CaseInsensitiveStringType)()
      

      就是这样;我的关联再次开始正确填充。

      同样,使用 int/GUID PK 而不是字符串来正确设计数据库要好得多,但如果必须这样做,这是一种“修复”NHibernate 的好方法。

      【讨论】:

      • 如果您认为您可能需要担心这一点,请将 .Trim() 添加到 String.Equals 中的 x 和 y。
      【解决方案4】:

      没有这个选项,但您可以使用 QBE 实现相同的效果

      Example.create(parent).ignoreCase() 
      

      【讨论】:

        【解决方案5】:

        我不明白你的问题:

        • 当你用Get方法通过PK查询时,返回的对象没有关系的值
        • 当您通过另一种查询进行查询时(示例将很有用),关系不为空?

        【讨论】:

          猜你喜欢
          • 2023-03-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-09-27
          • 2011-05-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多