Есть проблема с EF 4.0 и ObjectStateManager (я думаю)

У меня серьезная проблема, у меня есть уникальный ключ в поле в БД, я использую Oracle (поставщик Devart).

В первый раз, когда я преформирую Insert -> (_objectSet.Add(entity)) через свой репозиторий, все в порядке,

Кстати: я использую модель только для кода и CTP5.

Затем, если я хочу вставить его снова, он выдает ошибку, что у меня есть «ограничение уникального ключа», и это тоже нормально.

После этого, что бы я ни делал, всегда выдает одну и ту же ошибку!

Что это такое и как это исправить?

Заранее спасибо.


person IamStalker    schedule 10.03.2011    source источник
comment
Вы должны уточнить, что это значит: после этого, что бы я ни делал, это всегда выдает одну и ту же ошибку!   -  person Ladislav Mrnka    schedule 10.03.2011
comment
Вы правы, извините, я изменил все значения в объекте (новый объект)   -  person IamStalker    schedule 10.03.2011
comment
Вы не можете вносить изменения в новую сущность, поскольку старая уже отслеживается по контексту. Измените значения в старом, как @zmurf описал в своем ответе.   -  person Ladislav Mrnka    schedule 10.03.2011
comment
Извините, как мне получить старую сущность?   -  person IamStalker    schedule 10.03.2011


Ответы (3)


Вы пытаетесь сделать .Add(entity) с той же сущностью? Тогда вы получите эту ошибку. Если вы хотите что-то изменить в этом объекте, просто внесите изменения, например «entity.rowname = value», а затем сохраните, не пытаясь выполнить .Add(entity), и все должно работать нормально.

Как вы обычно это делаете, примерно так.

Создайте новую строку в базе данных:

Entity entity = new Entity();
entity.value = value;
db.Entity.AddObject(entity);
db.SaveChanges();

Получить и отредактировать строку:

var entity = db.Entity.SingleOrDefault(e => e.value == value);
entity.value = newValue;
db.SaveChanges();

Вы также можете сделать что-то подобное без проблем

Entity entity = new Entity(); //creating a new Entity
entity.value = 1;             //Setting a value on the new Entity
db.Entity.AddObject(entity);  //Adding the Entity to the context
db.SaveChanges();             //Saving the record to the database
entity = db.Entity.SingleOrDefault(e => e.value == 2); //retrieving another, already added record 
entity.value = 5;             //Changing the value on the retrieved record
db.SaveChanges();             //Saving the change to the database
entity = new Entity();        //creating yet another new Entity
entity.value = 8;             //setting the value on the second new Entity
db.Entity.AddObject(entity);  //adding the Entity to the context
db.SaveChanges();             //Saving the second new Entity to the database

Вы не можете НЕ поступать так

var entity = db.Entity.SingleOrDefault(e => e.value == value);
entity.value = newValue;
db.Entity.AddObject(entity); //WRONG!
db.SaveChanges();

Или это

Entity entity = new Entity();
entity.value = value;
db.Entity.AddObject(entity);
db.SaveChanges();
entity.value = newValue;
db.Entity.AddObject(entity); //WRONG!
db.SaveChanges();

В этом случае он попытается вставить уже отслеженный объект в качестве новой строки с тем же ключом и будет жаловаться, что уже есть предыдущая строка с тем же ключом, выдавая ошибку «уникальное ограничение ключа».

person mattsson    schedule 10.03.2011
comment
Как я сказал выше парню наверху, я делаю эти изменения и ничего. - person IamStalker; 10.03.2011
comment
Извините, может быть, меня неправильно поняли, проблема гораздо глубже. Я установил для себя уникальное ограничение, что если кто-то поместит данные, например, personid не (первичный или уникальный ключ) в первый раз, ответ ef4 в порядке, это говорит, что у вас есть ограничение уникального ключа в этом столбце, но если я изменю personid для другого, он по-прежнему говорит одно и то же, это работает до тех пор, пока в первый раз не было введено ограничение уникального ключа, после чего оно перестало работать. Я думаю, может быть, что-то не так с провайдером Devart, который держит кэш, но они его проверяют, а пока я жду. - person IamStalker; 12.03.2011
comment
Ааа.. Да.. Тогда я совершенно неправильно понял вопрос. В этом случае вам придется (как вы указываете в своем ответе) отсоединить объект. - person mattsson; 21.03.2011

@IamStalker, не могли бы вы указать более подробную информацию об ошибке?
Если возможно, отправьте сообщение здесь или отправьте нам пример кода, который вы используете для добавления и обновления объекта, или даже небольшой тестовый проект с кодом POCO объектов БД.

person Devart    schedule 10.03.2011
comment
Я отправил вам ссылку, если я делаю что-то не так, как должно быть. - person IamStalker; 10.03.2011
comment
Я отправил в поддержку Devart три дня назад электронное письмо с примером проекта и не получил никакого ответа, почему? - person IamStalker; 13.03.2011
comment
@IamStalker, мы ответили вам по электронной почте. Причина, по-видимому, заключается в реализации Insert. После добавления кода, выполняющего присоединение связанных сущностей, все работает нормально. - person Devart; 14.03.2011
comment
Нет, это не работает, я прикрепил ваш код, как и вы, и он все еще не работает. - person IamStalker; 15.03.2011

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

Я получил этот ответ от Андрея в Devart.

person IamStalker    schedule 17.03.2011