3

私の Entity Framework 4 モデル (MS SQL Server Express で動作する) には、Patient-PatientDevice-Device という多対多の関係があります。私は 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 を返す際の何が問題になっていますか?

4

1 に答える 1

1

その理由は、クラスタイプがハッシュコードの一部ではなく、エンティティフレームワークが異なるタイプを区別するのが難しいためである可能性があります。

次のことを試してください。

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

もう1つの問題は、GetHashCode()特定の状況下でオブジェクトの存続期間中にの結果が変更されない可能性があり、これらがエンティティフレームワークに適用される可能性があることです。Idこれは、作成時のbegin0と一緒に問題を引き起こします。

の代替手段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から取得。

于 2010-11-15T14:59:38.773 に答える