为什么我不能在EF4中的多对多实体上覆盖GetHashCode?

时间:2010-11-15 14:55:18

标签: c# entity-framework many-to-many gethashcode

我的Entity Framework 4模型(与MS SQL Server Express一起使用)之间存在多对多关系:Patient-PatientDevice-Device。我正在使用Poco,所以我的PatientDevice-class看起来像这样:

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-class中取消注释GetHashCode,患者仍然会提前添加PatientDevice。

覆盖GetHashCode并返回Id?

有什么问题

1 个答案:

答案 0 :(得分:1)

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

尝试以下方法:

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

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

GetHashCode()的替代方案是:

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