当重写GetHashCode()时,实体框架6在SaveChanges()上引发异常

时间:2017-09-06 23:28:20

标签: c# entity-framework entity-framework-6

执行以下两行

DBContext.DbSet.Remove(DBContext.DbSet.First(x => x.Id == someExistingId));
DBContext.SaveChanges();
当我在SaveChanges()实体类型上覆盖GetHashCode()时,

会导致DbSet上抛出以下异常。

  

不允许与处于“已删除”状态的实体添加关系。

我正在使用T4模板生成POCO对象并覆盖GetHashCode()中的partial。如果我只注释GetHashCode()覆盖,代码将按预期执行。

GetHashCode()覆盖只返回Id.GetHashCode()Idint

是否存在与使用实体框架POCO覆盖GetHashCode()相关的一些限制?

1 个答案:

答案 0 :(得分:1)

来自实体框架documentation

  
      
  • 您仍应遵循指南(Eric Lippert有great post on this)来实施Equals和GetHashCode
  •   
  • 如果你的   hashcode / equality算法不能保证不变性和   在任何时候都是独特的,你需要确保你的   集合导航属性使用引用相等   比较。对于HashSet传递   System.Data.Entity.Infrastructure.ObjectReferenceEqualityComparer to   构造函数(或创建自己的基于引用的相等比较器,   像下面的代码片段应该工作)。不要使用List作为   对于像这样的方法,它总是会使用重写的Equals方法   删除。
  •   
public class Category
{
    public Category()
    {
        Products = new HashSet<Product>(new ObjectReferenceEqualityComparer());
    }

    public string CategoryId { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Product> Products { get; set; }
}
[Serializable]
public sealed class ObjectReferenceEqualityComparer : IEqualityComparer<object>
{
    bool IEqualityComparer<object>.Equals(object x, object y)
    {
        return ReferenceEquals(x, y);
    }

    int IEqualityComparer<object>.GetHashCode(object obj)
    {
        return RuntimeHelpers.GetHashCode(obj);
    }
}