如何实现IEquatable< T>.当可变字段是相等的一部分时-GetHashCode问题 [英] How to implement IEquatable<T> when mutable fields are part of the equality - Problem with GetHashCode

查看:108
本文介绍了如何实现IEquatable< T>.当可变字段是相等的一部分时-GetHashCode问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在应用程序中使用实体框架.

I am using Entity Framework in my application.

我使用实体的局部类在IEquatable<T>接口中实现了

I implemented with the partial class of an entity the IEquatable<T> interface:

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

现在在我的代码中,我以这种方式使用它:

Now in my code I use it this way:

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对实体进行比较.

Note (I checked in the debugger visualizer) that the EntityCollection class stores its entities in HashSet so it has to do with the GetHashCode function, I want it to depend on the ID so entities are compared by their IDs.

问题是当我点击保存时,ID从0更改为它的db值. 因此,问题是我如何拥有一个经过适当哈希处理的可等于对象.

The problem is that when I hit save, the ID changes from 0 to its db value. So the question is how can I have an equatable object, being properly hashed.

请帮助我(按ID)查找GetHashCode函数中的问题以及可以进行哪些更改以使其起作用.

Please help me find what's wrong in the GetHashCode function (by ID) and what can I change to make it work.

非常感谢.

推荐答案

您已经使用了可变字段(AddressId)作为哈希的一部分-不幸的是,该字段注定要失败.我的意思是:添加时AddressId为0? -1?到底是什么都没关系,但这不是最终的ID,而是与该键/哈希一起存储的.保存时,实际 ID(数据库中的IDENTITY列)将更新到对象中.

You've used a mutable field (AddressId) as part of the hash - that is unfortunately doomed. By which I mean: when you add it, the AddressId is 0? -1? it doesn't matter what exactly, but it isn't the final id - and it is stored with this key / hash. When you save it, the actual id (the IDENTITY column from the database) is updated into the object.

很简单,如果此值作为字典的一部分可以更改,则您不能可靠地对该值进行哈希处理.一种可能的解决方法是考虑工作单元,即插入物是工作单元.含义:如果数据等的寿命仅此而已,那么它就不是问题,因为您在保存数据后将永远不会尝试访问该数据.随后(在不同的上下文中)加载数据也应该很好,因为id在生存期内不会发生变化.

Quite simply, you cannot reliably hash against this value if it can change when it is part of a dictionary. One possible workaround would be to consider the unit-of-work, i.e. an insert is a unit-of-work. Meaning: if the data etc only lives as long as this, then it is a non-issue as you will never attempt to access the data after saving it. Subsequently (in a different context) loading the data should be fine too, as the id doesn't then change during the lifetime.

或者:删除此哈希/等式.

Alternatively: drop this hash/equality.

这篇关于如何实现IEquatable&lt; T&gt;.当可变字段是相等的一部分时-GetHashCode问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆