Объект с таким же ключом уже существует в ObjectStateManager - PullRequest
1 голос
/ 18 октября 2011

Эта ошибка была задана по поводу много. Но ни один из случаев, я думаю, не относится к моему конкретному случаю, или, по крайней мере, не совсем.

Я создаю новую сущность с двумя навигационными свойствами, которые являются коллекциями. И сущность, и свойства навигации являются новыми сущностями, которых нет в базе данных. Моя проблема в том, что всякий раз, когда я пытаюсь присоединить сущность к контексту, если в какой-либо из коллекций есть более 1 элемента, я получаю вышеупомянутое исключение.

Я получаю эту ошибку по инструкции Attach() в следующем коде:

using (var context = new NSModel())
{
    context.Notifications.Attach(e);
    context.ObjectStateManager.ChangeObjectState(e,
    StateHelpers.GetEquivalentEntityState(e.State));

    foreach (NavigationProperty1 np in e.NavigationProperty1s)
        context.ObjectStateManager.ChangeObjectState(np,
        StateHelpers.GetEquivalentEntityState(np.State));

    foreach (NavigationProperty2 np in e.NavigationProperty2s)
        context.ObjectStateManager.ChangeObjectState(np,
        StateHelpers.GetEquivalentEntityState(np.State));

    context.SaveChanges();
    return e;
}   

Код предназначен для веб-сайта, поэтому объекты не сохраняют состояния, а контекст создается и удаляется при каждом вызове ...

Есть идеи?

1 Ответ

3 голосов
/ 18 октября 2011

И сущность, и свойства навигации являются новыми сущностями, которых нет в базе данных.

Тогда возникает вопрос: почему вы используете Attach?Используя Attach, вы сообщаете EF, что объекты равны в базе данных, а EF будет рассматривать значения свойств первичного ключа как значения столбца PK в базе данных.Поскольку эти свойства должны быть уникальными, EF будет жаловаться, как только у вас будет два объекта с одинаковыми значениями ключа.Вполне возможно, что у вас есть такая ситуация, когда у вас есть автоматически сгенерированные идентификаторы в качестве ключевых свойств и вы не устанавливаете значения при создании сущностей.

Простой пример:

public class Parent
{
    public Parent
    {
        Children = new List<Child>();
    }

    public int Id { get; set; }
    public ICollection<Child> Children { get; set; }
}

public class Child
{
    public int Id { get; set; }
}

Этот код...

using (var ctx = new MyContext())
{
    var parent = new Parent();
    var child1 = new Child();   // <- Id is 0
    var child2 = new Child();   // <- Id is 0 as well

    parent.Children.Add(child1);
    parent.Children.Add(child2);

    ctx.Parents.Attach(parent);  // <- exception here

    //...
}

... вызовет ваше исключение, потому что EF пытается присоединить два разных дочерних экземпляра с одним и тем же ключом 0.Когда присоединяется второй дочерний элемент child2, он говорит: «Объект (а именно child1) с тем же ключом (а именно 0) уже существует в ObjectStateManager».

Если вы хотите добавитьвесь граф объектов как новые объекты в базе данных вы можете просто вызвать context.Notifications.AddObject(e); вместо Attach.

...