2016-05-26 5 views
0

В моем School EF Model у меня есть Kids и Tutorials во многих отношениях. Предположим, что в Kids и Tutorials есть существующие элементы, теперь мы просто хотим изменить существующие отношения. То есть, чтобы добавить/удалить некоторые уроки от ребенка.Entity Framework Обновление многих из многих отношений правильно

var kid; //the request target to modify relationships 
//kid.Tutorials has the old existing relationships to be modified by add/del 
var tutorialsToAdd; //the request to add relationships 
var tutorialsToDel; //the request to del relationships 
using (var conn = new SchoolEFModels(efConnectionStr)) { 
    conn.Kids.Attach(kid); 
    kid.Tutorials.ForEach(t => conn.Tutorials.Attach(t)); 
    kid.Tutorials.AddRange(tutorialsToAdd); //simple add extension in batch 
    kid.Tutorials.RemoveRange(tutorialsToDel); //simple del extension in batch 
    conn.SaveChanges(); 
} 

Когда я делаю это, я исключение, говоря:

"Cannot insert duplicate key in object 'dbo.Tutorials'. The duplicate key value is (10)."

я могу видеть, EF пытается создать новый учебник элементов вместо обновления существующего отношения для меня. Это то, чего я не хочу. Вы меня неправильно поняли EF!

Что не так с моим кодом? Как мне обновить отношения «многие-ко-многим»?

+0

https://msdn.microsoft.com/en-us/magazine/dn166926.aspx –

+0

@GertArnold, это для меня продажа MVC Scaffolding. в частности, не говорили о обработке обновлений для многих-ко-многим. Мое приложение имеет другую структуру, чем это. Поэтому я все еще потерял :( – Tom

ответ

0

Я понял.

Добавление/удаление приведет к тому, что EntityState превратится в Добавлен/Удален. Поэтому, заставляя его повторно вставлять существующие идентификаторы в качестве упомянутой статьи, поблагодарите Герта за ссылку.

Таким образом, при изменении каждого из conn.entry(kid/tutorials).State в EntityState.Modified, а затем вызвать conn.ChangeTracker.DetectChanges(); затем conn.SaveChanges(); будет обновлять только многие-ко-многим таблице, как ожидалось.

UPDATE:

Одна вещь, вы должны быть осторожны Тхо. Если список объектов в памяти «Дети» и «Учебники» связаны друг с другом. например Kids[0].Tutorials[0] == Tutorials[0] && Tutorial[0].Kids[0] == Kids[0] EF не сможет справиться с этой мертвой петлей для вас. Сначала вам нужно разбить эту круговую ссылку. Для этого мой подход заключается в том, чтобы открыть Connection и прочитать Kid out Includes (Tutorials), а затем использовать результат, чтобы обновить отношения многих-многих, но не использовать объекты in-memory.

Смежные вопросы