.net 具有字符串主键和关系的NHibernate

.net 具有字符串主键和关系的NHibernate,.net,nhibernate,nhibernate-mapping,.net,Nhibernate,Nhibernate Mapping,我刚刚被这个问题难住了一个小时,我终于恼火地发现了这个问题 环境 我有一个表,它使用一个字符串作为主键,这个表有各种各样的多对一和多对多的关系,所有这些都与主键无关 当从表中搜索多个项目时,所有关系都会返回。但是,每当我试图通过主键(字符串)获取对象时,它不会返回任何关系,它们总是设置为0 部分解决方案 因此,我查看了日志,查看SQL在做什么,并返回正确的结果。所以我以各种各样的随机方式尝试了各种各样的事情,最终得出结论。将字符串传递到get方法的情况与数据库中的情况不完全相同,因此当它尝试将关

我刚刚被这个问题难住了一个小时,我终于恼火地发现了这个问题

环境

我有一个表,它使用一个字符串作为主键,这个表有各种各样的多对一和多对多的关系,所有这些都与主键无关

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

部分解决方案

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

真正的解决方案


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

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

return session.Get<T>(id);
返回会话.Get(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);
}
公共商户GetMerchantById(字符串id)
{
返回会话.Get(id);
}

对此没有选择,但您可以使用QBE实现同样的效果

Example.create(parent).ignoreCase() 

我不明白你的问题:

  • 通过PK with Get方法进行查询时,返回的对象对于关系没有值
  • 当您通过另一种查询进行查询时(举个例子会很有用),关系不是空的吗

为了保持一致性,请修改以下内容:

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

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

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

这是我的解决方法(这是一个解决方法;我正在处理一个设计糟糕的就地数据库)

最初来源于:

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

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

就这样,;我的关联开始重新正确填充


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

可以发布映射文件吗?新添加的项目的大小写正确吗?你最近更新过NHibernate吗?SQL通常是区分大小写的,但是使用“LIKE”语句时,它们可能都取决于方言,但在解析关系时,您不希望使用它。如果您认为可能需要担心,请将Add-in.Trim()添加到字符串中的x和y。
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
Id(Function(x) x.Id).GeneratedBy.Assigned().CustomType(Of CaseInsensitiveStringType)()