代码之家  ›  专栏  ›  技术社区  ›  Papa Mufflon

为什么不能重写EF4中多对多实体的GetHashCode?

  •  3
  • Papa Mufflon  · 技术社区  · 14 年前

    在我的实体框架4模型(与MS SQL Server Express一起工作)中,我有一个多对多的关系:病患设备。我正在使用Poco,因此我的PatientDevice类如下所示:

    public class PatientDevice
    {
        protected virtual Int32 Id { get; set; }
        protected virtual Int32 PatientId { get; set; }
        public virtual Int32 PhysicalDeviceId { get; set; }
        public virtual Patient Patient { get; set; }
        public virtual Device Device { get; set; }
    
        //public override int GetHashCode()
        //{
        //    return Id;
        //}
    }
    

    当我这样做的时候,所有的工作都很好:

    var context = new Entities();
    var patient = new Patient();
    var device = new Device();
    
    context.PatientDevices.AddObject(new PatientDevice { Patient = patient, Device = device });
    context.SaveChanges();
    
    Assert.AreEqual(1, patient.PatientDevices.Count);
    
    foreach (var pd in context.PatientDevices.ToList())
    {
        context.PatientDevices.DeleteObject(pd);
    }
    context.SaveChanges();
    
    Assert.AreEqual(0, patient.PatientDevices.Count);
    

    但是,如果我在PatientDevice类中取消对GetHashCode的注释,那么患者仍然可以在前面添加PatientDevice。

    重写GetHashCode并返回ID时出错了什么?

    1 回复  |  直到 14 年前
        1
  •  1
  •   Pieter van Ginkel    14 年前

    原因很可能是类类型不是哈希代码的一部分,并且实体框架很难区分不同的类型。

    请尝试以下操作:

    public override int GetHashCode()
    {
        return Id ^ GetType().GetHashCode();
    }
    

    另一个问题是 GetHashCode() 在某些情况下,在对象的生命周期内可能不会发生变化,这些变化可能适用于实体框架。这个加上 Id 创建0时开始0也会产生问题。

    替代 获取哈希代码() 是:

    private int? _hashCode;
    
    public override int GetHashCode()
    {
        if (!_hashCode.HasValue)
        {
            if (Id == 0)
                _hashCode.Value = base.GetHashCode();
            else
                _hashCode.Value = Id;
                // Or this when the above does not work.
                // _hashCode.Value = Id ^ GetType().GetHashCode();
        }
    
        return _hasCode.Value;
    }
    

    取自 http://nhforge.org/blogs/nhibernate/archive/2008/09/06/identity-field-equality-and-hash-code.aspx