#c# #.net #linq #entity-framework #entity-framework-4
#c# #.net #linq #entity-framework #entity-framework-4
Вопрос:
Если у меня есть объект Book, у которого есть дочерняя коллекция комментариев, могу ли я обновить Книгу и список комментариев вместе с entity framework?
Я пытался :
_context.Books.Attach(book);
_context.ObjectStateManager.ChangeObjectState(book, EntityState.Modified);
_context.SaveChanges();
безуспешно…
получаю следующую ошибку в первой строке:
An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key
Комментарии:
1. «безрезультатно» не очень описывает. Что точно произойдет, когда вы попробуете это?
2. Я получаю сообщение об ошибке: ‘Объект с таким же ключом уже существует в ObjectStateManager. ObjectStateManager не может отслеживать несколько объектов с одним и тем же ключом’
3. В какой строке?
Attach
Строка?4. Вы
Detatch
прочитали книгу перед тем, как попыталисьAttach
это сделать? т.е. можете ли вы показать код перед этим?..5. Я не пытался сначала отсоединить книгу… На данный момент это единственные три строки в моем методе. Передаю объект book в качестве параметра. Как вы можете заметить, я новичок в EF…
Ответ №1:
Скорее всего, у вас циклическая зависимость (Books имеет ссылку на внешний ключ для комментариев, а комментарии возвращаются к книгам). В этом случае UpdateTranslator в EF не может определить порядок зависимостей. Насколько я могу судить, в этой модели разработки нет способа передать подсказку EF, чтобы указать, каков порядок.
Самый распространенный способ решить эту проблему (который я видел) — выполнить двухфазную фиксацию. Внесите изменения в Книгу, сохраните ее, затем внесите изменения в Комментарии и сохраните это. Я обнаружил, что использование подхода Code First позволяет более конкретно определять взаимосвязи и тем самым устранять многие проблемы, с которыми я сталкивался.
Редактировать:
Вот пример:
using (var context = new BookContext())
{
book.Title = "This is the new title";
context.SaveChanges();
book.Comments.Add(new Comment("This is a comment"));
context.SaveChanges();
}
При наличии циклической зависимости вы не смогли бы выполнить вышеописанное одним вызовом SaveChanges
.
Комментарии:
1. если код, который я опубликовал выше, пытается выполнить все за один вызов, как я могу изменить его, чтобы разделить на 2 части?
2. Я не уверен, что у меня действительно есть циклическая зависимость… У моего объекта Comment есть свойство BookID, а у моего объекта Book есть свойство навигации по комментариям… В самой базе данных определенно нет циклической зависимости
3. Вы пробовали выполнять два отдельных
SaveChanges
, чтобы посмотреть, решит ли это проблему? Дальнейшую отладку было бы сложно выполнить без лучшего представления модели.