gpt4 book ai didi

c# - 如何为具有标识列的 NHibernate 实体实现 GetHashCode?

转载 作者:太空宇宙 更新时间:2023-11-03 10:59:00 24 4
gpt4 key购买 nike

我得出的结论是,不可能为具有标识列的 NHibernate 实体正确实现 GetHashCode()。我找到的唯一可行的解​​决方案是返回一个常量。请参阅下面的解释。

这显然很糟糕:所有字典搜索实际上都变成了线性搜索。我错了吗?有没有我错过的解决方法?

解释

假设我们有一个 Order 实体,它引用一个或多个这样的 Product 实体:

class Product
{
public virtual int Id { get; set; } // auto; assigned by the database upon insertion
public virtual string Name { get; set; }
public virtual Order Order { get; set; } // foreign key into the Orders table
}

“Id”就是所谓的 IDENTITY SQL Server 术语中的列:插入记录时由数据库自动生成的整数键。

现在,我有哪些选择来实现 Product.GetHashCode()?我可以根据它

  • Id
  • 名称
  • 产品对象的标识(默认行为)

这些想法都行不通。如果我将我的散列码基于 Id,则当对象被插入数据库时​​它会发生变化。至少在 NHibernate.SetForNet4 存在的情况下,以下实验表明会中断:

/* add product to order */

var product = new Product { Name = "Sushi" }; // Id is zero
order.Products.Add(product); // GetHashCode() is calculated based on Id of zero
session.SaveOrUpdate(order);

// product.Id is now changed to an automatically generated value from DB
// product.GetHashCode() value changes accordingly
// order.Products collection does not like it; it assumes GetHashCode() does not change

bool isAdded = order.Products.Contains(product);

// isAdded is false;
// the collection is looking up the product by its new hash code and not finding it

基于对象标识的 GetHashCode()(即保留 Product 的默认实现)也不能很好地工作,它之前在 StackOverflow 上有介绍。如果 Name 是可变的,则基于 NameGetHashCode() 显然不是一个好主意。

那么,还剩下什么?唯一对我有用的是

class Product
{
...
override public GetHashCode() { return 42; }
}

感谢您阅读这个冗长的问题。您对如何让它变得更好有什么想法吗?

附言。请记住,这是一个 NHibernate 问题,而不是集合问题。集合类型和操作顺序不是任意的。它们与 NHibernate 的工作方式有关。例如,我不能简单地将 Order.Products 设为 IList 之类的东西。它将具有重要的意义,例如需要索引/顺序列等。

最佳答案

我会将散列码(显然是相等性)基于 Id,这是正确的做法。您的问题源于您在对象位于字典中时修改 Id 的事实。当对象在字典或哈希集中时,它们在哈希码和相等性方面应该是不可变的。

你有两个选择-

  1. 在数据库中存储项目之前不要填​​充字典或哈希集
  2. 在将对象保存到数据库之前,将其从字典中删除。将其保存到数据库中,然后再次将其添加到字典中。

更新

这个问题也可以通过使用其他映射来解决

  1. 您可以使用包映射 - 它将映射到 IList 并且应该可以正常工作。无需使用哈希集或字典。
  2. 如果数据库模式在您的控制之下,您可能希望考虑添加索引列并使关系有序。这将再次映射到 IList,但将具有 List 映射。

性能会有所不同,具体取决于您的映射和场景(请参阅 http://nhibernate.info/doc/nh/en/#performance-collections-mostefficientupdate)

关于c# - 如何为具有标识列的 NHibernate 实体实现 GetHashCode?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18388826/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com