Entity Framework 4.1 Code-First и вставка новых отношений «один ко многим» - PullRequest
8 голосов
/ 24 июня 2011

У меня возникли проблемы при привязке нового графа объекта к контексту с отношением один ко многим. Я использую выпуск Entity Framework 4.1 и реализую подход Code-First. Я использую существующую базу данных SQL 2008 и реализовал контекст, полученный из DbContext. У меня есть два класса, Персона и Адрес. Человек может содержать 0 или более адресов, определенных как таковые.

public class Person 
    {
        public Person()
        {
            Addresses = new List<Address>();
        }

        public int PersonId { get; set; }
        ***Additional Primitive Properties***

        public virtual ICollection<Address> Addresses { get; set; }

    }

public class Address 
    {
        public int AddressId { get; set; }
        public int AddressTypeId { get; set; }
        ***Additional Primitive Properties***

        public int PersonId { get; set; }
        public virtual Person Person { get; set; }
    }

Я пытаюсь создать новый экземпляр Person с двумя адресами. Однако, когда я добавляю эту структуру в контекст и сохраняю, сохраняется только первый адрес в коллекции. Второй имеет свойство навигации Person, установленное в ноль, и не связан с объектом Person, однако, первый в списке связан.

var person = new Person();

var mailingAddress = new Address() { AddressTypeId = 1 };
person.Addresses.Add(mailingAddress);

var billingAddress = new Address() { AddressTypeId = 2 };
person.Addresses.Add(billingAddress);

context.People.Add(entity);
context.SaveChanges();

Это не вызывает исключение, но второй элемент в коллекции адресов просто не сохраняется.

Есть ли у кого-нибудь хорошие идеи о том, почему спасется только первое? Спасибо.

Ответы [ 3 ]

10 голосов
/ 24 июня 2011

После нескольких часов устранения неполадок / проб и ошибок я решил свою проблему. Мои классы POCO также используются в автономной среде, где объекты отсоединяются от контекста, модифицируются, а затем снова присоединяются.

Чтобы определить, какие элементы коллекции свойств навигации были затронуты, я переопределил методы Equals и GetHashCode в классе Address для определения равенства. Очевидно, это влияет на способность EF 4.1 вставлять полную коллекцию объектов свойств навигации ???

Вот оригинальные методы равенства, которые вызвали проблему:

public override bool Equals(object obj)
{
    Address address = obj as Address;
    if (address == null) return false;
    return address.AddressId == this.AddressId;
}

public override int GetHashCode()
{
    return this.AddressId.GetHashCode();
}

Чтобы исправить проблему, я создал собственный компаратор равенства для объекта навигации, а не для включения его непосредственно в класс адресов.

public class AddressEqualityComparer : IEqualityComparer<Address>
{
    public bool Equals(Address address1, Address address2)
    {
        if (address1.AddressId == address2.AddressId)
            return true;
        else
            return false;
    }

    public int GetHashCode(Address address)
    {
        return address.AddressId.GetHashCode();
    }
}

Мой метод context.People.Add работал, как и ожидалось, после того, как я сделал это изменение.

Если кто-нибудь знает, почему переопределение методов равенства в классе вызывает EF 4.1, чтобы вставить только первый элемент в коллекции, который будет отличная информация.

1 голос
/ 13 октября 2011

Как уже упоминалось, это потому, что метод GetHashCode использует ID всех братьев и сестер, который будет равен 0 в точке сравнения Entity Framework. Прокомментируйте это, и вам будет хорошо.

У меня была та же самая проблема, и эта часть позволила мне это сделать. Я даже не удосужился взглянуть на свой код EntityBase ... он такой старый и не изменился навсегда до сих пор.

Большое спасибо за ваши исследования!

0 голосов
/ 24 июня 2011

Вот еще один способ попытаться добавить код.Стоит выстрел.Этот код может быть не точным, я напечатал от руки.

var person = new Person();

person.Addresses.Add(new Address()
{
   AddressTypeId = 1
}),
new Address()
{
   AddressTypeId = 2
});

context.People.Add(entity);
context.SaveChanges();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...