EF4 добавление нескольких сущностей (объект с таким же ключом уже существует в ObjectStateManager) - PullRequest
3 голосов
/ 17 ноября 2010

У меня есть объект с множеством свойств.Куча этих больших объектов должна быть вставлена ​​в БД, но с изменением только одного свойства.Свойство, которое будет изменяться, не является первичным ключом.Первый раз SaveChanges завершается успешно, но последующие сбои с «Объект с таким же ключом уже существует в ObjectStateManager .....».Вот поток кода:

    //create the entity and set the properties that don't change
    TheLargeObject obj = new TheLargeObject();
    obj.Prop1 = 
    obj.Prop2 = 
    ...
    obj.Prop20 = 

    //create a list of values that differ between each entity
    List<int> validIds = new List<int>();

    private static void SaveToDatabase(TheLargeObject obj, List<int> validIds)
    {

        foreach (int id in validIds)
        {
            //this is the only property that changes
            obj.KeyId = id;

            //make a copy - do we really need this?
            TheLargeObject newobj = new TheLargeObject();
            newobj = obj;

            using(Entities objContext = new Entities())
            {
                objContext.TheLargeObjects.AddObject(newobj); //ERROR: An object with the same key already exists in the ObjectStateManager.  
                objContext.SaveChanges();
            }
        }
    }

Я только начинаю с EF4, так что, вероятно, я поступаю неправильно.Спасибо

1 Ответ

8 голосов
/ 17 ноября 2010

Я не уверен, что вы пытаетесь сделать здесь.Главным образом это утверждение смущает меня:

Куча этих больших объектов должна быть вставлена ​​в БД, но с изменением только одного свойства.

Как можно новый объект (т.е. вставленный) будет изменяющимся ?Если он новый, что можно изменить?

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

Что я думаю, что вы делаете .AddObject, когда вы должны делать .Attach.

Вот как вы ВСТАВЛЯЕТЕ новый объект:

var newFoo = new Foo();
ctx.Foos.AddObject(newFoo);
newFoo.SaveChanges();

Вот как вы ОБНОВЛЯЕТЕ существующий объект:

var existingFoo = ctx.Foos.SingleOrDefault(x => x.Id == 1); // or however you want to get it
existingFoo.Name = "Changed foo";
newFoo.SaveChanges();

Или, если у вас есть отсоединенный объект:

var existingFoo = new Foo();
existingFoo.Name = "Foo name";
ctx.Foos.Attach(existingFoo);
ctx.SaveChanges();

Итак, я думаю в вашем примере ваш код должен просто выглядеть следующим образом:

objContext.TheLargeObjects.Attach(newObject);
objContext.SaveChanges();

В двух словах, если у вас есть сущность, которая вам положительна, уже существует в базе данных, и вы создали эту сущностьвручную используйте .Attach.Если у вас есть новый шлепающий новый объект, используйте .AddObject.

Однако, чтобы быть в безопасности - вы могли бы пойти и снова получить объект , внести необходимые изменения, а затем сделать .SaveChanges().

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

Надеюсь, это прояснит для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...