Почему я не могу переопределить GetHashCode для объекта «многие ко многим» в EF4? - PullRequest
3 голосов
/ 15 ноября 2010

У меня есть отношение многие ко многим в моей модели 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);

Но если я раскомментирую GetHashCode в PatientDevice-классеу пациента все еще есть PatientDevice, добавленный ранее.

Что плохого в переопределении GetHashCode и возврате идентификатора?

1 Ответ

1 голос
/ 15 ноября 2010

Причина вполне может быть в том, что тип класса не является частью хеш-кода, и что структура сущностей испытывает трудности при различении различных типов.

Попробуйте следующее:

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

Другая проблема заключается в том, что результат GetHashCode() может не измениться в течение срока службы объекта при определенных обстоятельствах, и они могут применяться к структуре сущности. Это вместе с Id begin 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.

...