Entity Framework 4, объекты POCO и ASP.Net MVC2. У меня есть отношения «многие ко многим», скажем, между объектами BlogPost и Tag. Это означает, что в моем сгенерированном T4 классе POCO BlogPost у меня есть:
public virtual ICollection<Tag> Tags {
// getter and setter with the magic FixupCollection
}
private ICollection<Tag> _tags;
Я прошу BlogPost и связанные теги из экземпляра ObjectContext и отправляю его на другой уровень (просмотр в приложении MVC). Позже я возвращаю обновленный BlogPost с измененными свойствами и измененными отношениями. Например, у него были теги «A», «B» и «C», а новые теги - «C» и «D». В моем конкретном примере нет новых тегов, и свойства тегов никогда не меняются, поэтому единственное, что следует сохранить, - это измененные отношения. Теперь мне нужно сохранить это в другом ObjectContext. (Обновление: теперь я пытался сделать в том же экземпляре контекста, но тоже потерпел неудачу.)
Проблема: я не могу заставить его правильно сохранять отношения. Я перепробовал все, что нашел:
- Controller.UpdateModel и Controller.TryUpdateModel не работают.
- Получение старого BlogPost из контекста и последующее изменение коллекции не работают. (разными методами из следующего пункта)
- Это, вероятно, сработает, но я надеюсь, что это просто обходной путь, а не решение :(.
- Пробовал функции Attach / Add / ChangeObjectState для BlogPost и / или тегов во всех возможных комбинациях. Не смогли.
- Это похоже на то, что мне нужно, но это не работает (я пытался исправить это, но не могу решить свою проблему).
- Пробовал ChangeState / Add / Attach / ... отношения объектов контекста. Не смогли.
«Не работает» означает в большинстве случаев, что я работал над данным «решением» до тех пор, пока оно не выдало ошибок и не сохранило хотя бы свойства BlogPost. Что происходит с отношениями, различается: обычно теги снова добавляются в таблицу тегов с новыми PK, и сохраненный BlogPost ссылается на них, а не на исходные. Конечно, у возвращаемых тегов есть PK, и перед методами сохранения / обновления я проверяю PK, и они равны тем, что есть в базе данных, поэтому, вероятно, EF думает, что это новые объекты, а эти PK являются временными.
Проблема, о которой я знаю, и может сделать невозможным найти автоматическое простое решение: при изменении коллекции объекта POCO это должно произойти с помощью вышеупомянутого свойства виртуальной коллекции, потому что тогда трюк FixupCollection обновит обратные ссылки на другом конце отношения "многие ко многим". Однако, когда View «возвращает» обновленный объект BlogPost, этого не произошло. Это означает, что, возможно, у моей проблемы нет простого решения, но это меня очень огорчит, и я бы возненавидел триумф EF4-POCO-MVC :(. Также это будет означать, что EF не может сделать это в среде MVC, в зависимости от того, что Используются типы объектов EF4 :(. Я думаю, что отслеживание изменений на основе снимков должно определить, что измененный BlogPost имеет отношения к тегам с существующими PK.
Кстати: я думаю, что такая же проблема возникает с отношениями один-ко-многим (так говорят Google и мой коллега). Я попробую дома, но даже если это сработает, это не поможет мне в моих шести отношениях «многие ко многим» в моем приложении :(.