5

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

情况

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

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

部分解决方案

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

真正的解决方案

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

4

5 回答 5

4

我在我的数据库中的 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);
}
于 2009-01-15T15:22:38.227 回答
1

为了一致性起见,请修改:

<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 映射的一部分?

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

于 2009-02-23T23:37:22.060 回答
1

这是我的解决方法(这是一种解决方法;我正在处理一个 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 的一种不错的方式。

于 2011-01-05T16:49:16.437 回答
0

我不明白你的问题:

  • 当您通过 PK 使用 Get 方法查询时,返回的对象对于关系没有任何值
  • 当您通过另一种查询进行查询时(示例将很有用),关系不为空吗?
于 2009-02-23T20:49:44.707 回答
0

对此没有选择,但您可以使用 QBE 实现相同的目标

Example.create(parent).ignoreCase() 
于 2009-02-09T14:23:47.003 回答