1

アプリケーションで Entity Framework を使用しています。

IEquatable<T>インターフェイスのエンティティの部分クラスで実装しました。

Partial Class Address : Implements IEquatable(Of Address) 'Other part generated
  Public Overloads Function Equals(ByVal other As Address) As Boolean _
      Implements System.IEquatable(Of Address).Equals
    If ReferenceEquals(Me, other) Then Return True
    Return AddressId = other.AddressId
  End Function

  Public Overrides Function Equals(ByVal obj As Object) As Boolean
    If obj Is Nothing Then Return MyBase.Equals(obj)
    If TypeOf obj Is Address Then 
      Return Equals(DirectCast(obj, Address)) 
  Else
    Return False
  End Function

  Public Overrides Function GetHashCode() As Integer
    Return AddressId.GetHashCode
  End Function
End Class

私のコードでは、次のように使用しています。

Sub Main()
  Using e As New CompleteKitchenEntities
    Dim job = e.Job.FirstOrDefault
    Dim address As New Address()

    job.Addresses.Add(address)
    Dim contains1 = job.Addresses.Contains(address) 'True
    e.SaveChanges()
    Dim contains2 = job.Addresses.Contains(address) 'False

    'The problem is that I can't remove it:
    Dim removed = job.Addresses.Remoeve(address) 'False

  End Using
End Sub

EntityCollection クラスはそのエンティティを HashSet に格納するため、GetHashCode 関数と関係があることに注意してください (デバッガ ビジュアライザで確認しました)。エンティティが ID で比較されるように、ID に依存するようにします。

問題は、保存を押すと、ID が 0 からその db 値に変わることです。したがって、問題は、適切にハッシュされた同等のオブジェクトをどのように取得できるかです。

GetHashCode 関数の何が問題なのか (ID で)、それを機能させるために何を変更すればよいかを教えてください。

どうもありがとう。

4

2 に答える 2

1

シールされていないクラスは実装しないでください。これは、と整合性のある方法でオーバーライドおよび実装されるIEquatable<T>派生クラスを保証する唯一の方法は、インターフェイス実装が仮想メソッドを呼び出すことであるためです。の唯一の目的は呼び出しのオーバーヘッドを回避することであり、封印されていないクラスでの安全な実装はそれを呼び出すことを回避できないため、そのような実装は目的を果たしません。Object.Equals()Object.GetHashCode()IEquatable<BaseType>Object.GetHashCode()Object.Equals(Object)IEquatable<T>Object.Equals(Object)IEquatable<T>

また、可変クラスタイプのオーバーライドObject.Equals(またはの実装)に対して強く助言します。構造体タイプが可変のパブリックフィールドを公開している場合でも、たとえばキーとして格納されている構造体のフィールドは不変であるIEquatable<T>ため、構造体は、可変であるかどうかに関係なく、オーバーライドObject.EqualsしてObject.GetHashCode、を実装することをお勧めします。IEquatable<theirOwnType>Dictionary

于 2012-08-27T17:46:58.330 に答える
1

変更可能なフィールド ( AddressId) をハッシュの一部として使用しました。残念ながら、これは運命づけられています。つまり、追加すると、AddressIdは 0 ですか? -1? 正確に何であるかは問題ではありませんが、最終的な ID ではなく、このキー/ハッシュと共に保存されます。保存すると、実際のID (IDENTITYデータベースの列) がオブジェクトに更新されます。

簡単に言えば、この値が辞書の一部であるときに変更される可能性がある場合、この値に対して確実にハッシュすることはできません。考えられる回避策の 1 つは、作業単位を考慮することです。つまり、挿入は作業単位です。意味: データなどがこの期間しか存続しない場合、保存後にデータにアクセスしようとすることは決してないため、問題はありません。その後(別のコンテキストで)データをロードしても問題ありません。IDは存続期間中に変更されないためです。

または、このハッシュ/等価を削除します。

于 2010-04-13T05:10:21.820 に答える