Entity Framework 4.1 Изменение объекта и дочерней коллекции

#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 , чтобы посмотреть, решит ли это проблему? Дальнейшую отладку было бы сложно выполнить без лучшего представления модели.