Давайте попробуем это так:
- Присоедините BlogPost к контексту. После присоединения объекта к контексту состояние объекта, всех связанных объектов и всех отношений устанавливается равным Не изменено.
- Используйте context.ObjectStateManager.ChangeObjectState, чтобы установить для вашего BlogPost значение Modified
- Итерация по коллекции тегов
- Используйте context.ObjectStateManager.ChangeRelationshipState, чтобы установить состояние для связи между текущим тегом и BlogPost.
- SaveChanges
Edit:
Полагаю, один из моих комментариев дал вам ложную надежду, что EF сделает слияние за вас. Я много играл с этой проблемой, и мой вывод гласит, что EF не сделает этого за вас. Я думаю, вы также нашли мой вопрос на MSDN . На самом деле таких вопросов в Интернете достаточно. Проблема в том, что неясно указано, как бороться с этим сценарием. Итак, давайте посмотрим на проблему:
проблемный фон
EF необходимо отслеживать изменения в сущностях, чтобы персистентность знала, какие записи необходимо обновить, вставить или удалить. Проблема заключается в том, что ObjectContext отвечает за отслеживание изменений. ObjectContext может отслеживать изменения только для прикрепленных объектов. Объекты, созданные вне ObjectContext, вообще не отслеживаются.
Описание проблемы
На основании приведенного выше описания мы можем четко заявить, что EF больше подходит для связанных сценариев, где сущность всегда привязана к контексту - типично для приложения WinForm. Для веб-приложений требуется отключенный сценарий, когда контекст закрывается после обработки запроса, а содержимое объекта передается как HTTP-ответ клиенту. Следующий HTTP-запрос предоставляет измененный контент объекта, который должен быть воссоздан, присоединен к новому контексту и сохранен. Отдых обычно происходит вне контекста контекста (многоуровневая архитектура с постоянным невежеством).
Решение
Так, как бороться с таким отключенным сценарием? При использовании классов POCO у нас есть 3 способа отслеживания изменений:
- Снимок - требуется тот же контекст = бесполезно для отключенного сценария
- Прокси-серверы динамического отслеживания - требуется тот же контекст = бесполезно для отключенного сценария
- Ручная синхронизация.
Ручная синхронизация на одном объекте - простая задача. Вам просто нужно присоединить сущность и вызвать AddObject для вставки, DeleteObject для удаления или установить состояние в ObjectStateManager в значение Modified для обновления. Настоящая боль возникает, когда вам приходится иметь дело с графом объектов, а не с одной сущностью. Эта боль еще хуже, когда вам приходится иметь дело с независимыми ассоциациями (теми, которые не используют свойство внешнего ключа) и отношениями многие ко многим. В этом случае вы должны вручную синхронизировать каждую сущность в графе объектов, а также каждое отношение в графе объектов.
Ручная синхронизация предлагается в качестве решения в документации MSDN: Присоединение и отсоединение объектов говорит:
Объекты прикреплены к объекту
контекст в неизменном состоянии. если ты
нужно изменить состояние объекта
или отношения, потому что вы знаете,
что ваш объект был изменен в
отдельное состояние, используйте один из
следующие методы.
Упомянутыми методами являются ChangeObjectState и ChangeRelationshipState из ObjectStateManager = отслеживание изменений вручную. Аналогичное предложение содержится в другой статье документации MSDN: Определение и управление отношениями говорит:
Если вы работаете с отключенным
объекты, которые вы должны вручную управлять
синхронизации.
Более того, в блоге 1068 *, связанном с EF v1, содержится критическая информация о поведении EF.
Причина решения
EF имеет множество «полезных» операций и настроек, таких как Обновить , Загрузить , ApplyCurrentValues , ApplyOriginalValues , MergeOption и т. Д. Но по моим исследованиям все эти функции работают только для одного объекта и влияют только на скалярные свойства (= не навигационные свойства и отношения). Я скорее не тестирую эти методы со сложными типами, вложенными в сущность.
Другое предлагаемое решение
Вместо реальной функциональности слияния команда EF предоставляет то, что называется Самопроверяемые объекты (STE), которые не решают проблему. Прежде всего, STE работает, только если один и тот же экземпляр используется для всей обработки. В веб-приложении это не так, если вы не сохраняете экземпляр в состоянии просмотра или сеанса. В связи с этим я очень недоволен использованием EF и собираюсь проверить возможности NHibernate. Первое наблюдение говорит о том, что NHibernate, возможно, обладает такой функциональностью .
Заключение
Я закончу эти предположения одной ссылкой на другой вопрос на форуме MSDN. Проверьте ответ Зеешана Хирани. Он является автором Entity Framework 4.0 Recipes . Если он говорит, что автоматическое объединение графов объектов не поддерживается, я верю ему.
Но все же есть вероятность, что я совершенно не прав, и в EF есть некоторые функции автоматического слияния.
Редактировать 2:
Как вы можете видеть, это было уже добавлено в MS Connect как предложение в 2007 году. MS закрыла его как нечто, что должно быть сделано в следующей версии, но на самом деле ничего не было сделано для улучшения этого пробела, кроме STE.