#c# #.net #entity-framework #wcf #odata
#c# #.net #entity-framework #wcf #odata
Вопрос:
У меня есть служебная ссылка на класс DataServiceContext в моем клиентском проекте.
Мне нужно создать новый объект и сохранить его в контексте базы данных.
Все идет хорошо, пока я сохраняю только этот объект, без каких-либо связанных объектов.
A a = new A();
context.AddToAs(a);
context.BeginSaveChanges(o=>{
//some after-save code there
}, null);
Однако код, подобный этому:
A a = new a(); //parent entity
B b = new b(); //child entity which has corresponding b.A navigation
//property and b.AId field for referencing 'A' entity primary
//key.
a.b = b;
context.AddToAs(a);
context.AddToBs(b);
context.SetLink(b, "A", a);
context.BeginSaveChanges(o=>{
//some after-save code here
}, null);
… сбой с ошибкой «Оператор INSERT конфликтует с ограничением ВНЕШНЕГО КЛЮЧА».
Конечно, я понимаю, что вновь созданный объект «A» имеет первичный ключ, равный «0», и соответствующие свойства навигации в объекте «B», например b.Помощь также равна «0» при сохранении. И это действительно вызывает проблему — «Объект» с первичным ключом «0» уже существует в базе данных.
Итак, я должен сначала сохранить объект «A», без присвоения каких-либо связанных объектов «B», чтобы объект «A» был сохранен и получил реальный идентификатор, а затем — присоединить объекты «B» к A и сохранить контекст еще раз, чтобы объекты «B» были сохранены.
Я более чем уверен, что я делаю там что-то ужасно неправильное, кто-нибудь может дать какие-либо предложения о том, как сделать это с помощью одного SaveChanges?
Ответ №1:
Я столкнулся с той же проблемой. Мое решение состояло в том, чтобы не связывать объекты в памяти. Я использовал только context.SetLink. Итак, для вашего примера, я думаю, это сработает:
A a = new a(); //parent entity
B b = new b(); //child entity which has corresponding b.A navigation
//property and b.AId field for referencing 'A' entity primary
//key.
// Omit this line. a.b = b;
context.AddToAs(a);
context.AddToBs(b);
context.SetLink(b, "A", a);
context.BeginSaveChanges(o=>{
//some after-save code here
}, null);
В моей ситуации созданные объекты не использовались после вызова save changes, поэтому не имело значения, что объекты не были связаны в памяти после вызова save. Если вам нужно, чтобы объекты также были связаны в памяти после вызова save, я могу попробовать две вещи:
- Загрузите объекты из контекста после их сохранения. Это немного ненужный вызов базы данных, но это означает, что загруженные объекты будут иметь правильную привязку.
- Вручную назначьте ассоциации (например, a.b = b;) после сохранения изменений.