5

私はこの問題に 1 時間悩まされていましたが、最終的に問題を発見しました。

状況

文字列を主キーとして使用するテーブルがあります。このテーブルには、この主キーから離れたさまざまな多対1および多対多の関係があります。

テーブルから複数のアイテムを検索すると、すべての関係が返されました。ただし、主キー (文字列) でオブジェクトを取得しようとすると、リレーションシップが返されず、常に 0 に設定されていました。

部分的な解決策

そこで、ログを調べて、SQL が何を行っていて、正しい結果が返されているかを確認しました。だから私はあらゆる種類のランダムな方法でさまざまなことを試し、最終的にそれがうまくいきました. get メソッドに渡される文字列の大文字と小文字の大文字と小文字は、データベースにあるものとまったく同じではありませんでした。そのため、リレーションシップ アイテムをメイン エンティティと一致させようとしたときに、何も見つかりませんでした(または、少なくとも NHIbernate は一致しませんでした)。上で述べたように、SQL は実際には正しい結果を返していたからです)

本当の解決策

他の誰かがこれに出くわしましたか? もしそうなら、NHibernate に SQL の結果をエンティティに一致させるときに大文字と小文字を区別しないようにするにはどうすればよいでしょうか? 以前は完全に機能していたのに、突然、文字列のケースに注意を払い始めたのはばかげています。

4

5 に答える 5

4

DB の 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」。NHibernateのマッピングの一部としてASP.NETWebサイトからの一時的なアセンブリを使用しているように見えますか?

ビジネスエンティティを独自のライブラリに移動して、アセンブリ名が常に同じになるようにします。

于 2009-02-23T23:37:22.060 に答える
1

これが私の回避策です(これは回避策です。IMOで設計が不十分なインプレースDBを扱っています)。

元のソース: 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 を使用して DB を正しく設計する方がはるかに優れていますが、必要な場合、これは NHibernate を「修正」する適切な方法です。

于 2011-01-05T16:49:16.437 に答える
0

私はあなたの問題を理解していません:

  • Getメソッドを使用してPKでクエリを実行すると、返されるオブジェクトには関係の値がありません
  • 別の種類のクエリでクエリを実行する場合(例が役立ちます)、関係は空ではありませんか?
于 2009-02-23T20:49:44.707 に答える
0

これにはオプションはありませんが、QBEを使用して同じことを達成できます

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