Зависит от того, что вы пытаетесь обновить. Прежде всего позвольте мне прояснить один важный факт - если у вас есть отдельный объектный граф (больше сущностей с отношением) и вы хотите передать все изменения в EF, вы отвечаете за то, чтобы сообщить EF, что изменилось в каждой сущности и каждом отношении - EF не будет помочь вам с этим.
Если вы пытаетесь обновить только Bar
экземпляров и не изменили отношения (= вы не добавили новые Bar
в Foo
или не удалили Bar
из Foo
), вам просто нужно итерируйте Bars
и установите их в состояние Modified
.
Если вы также изменили содержимое коллекции Bars
, весь процесс станет действительно сложным, и подход зависит от того, как вы определили свои сущности = Если вы используете независимый или внешний ключ связи .
В случае связывания внешнего ключа (Bar
имеет свойство FK в качестве свойства = в Bar
у вас есть что-то вроде FooId
), вы следуете тому же подходу, что и в начале. Вы повторяете Bars
и устанавливаете состояние на:
Modified
, если существующий Bar
был присвоен Foo
Added
, если новый Bar
был присвоен Foo
Есть одна большая проблема. Если вы удалили несколько экземпляров Bar
из коллекции Bars
, вы также должны присоединить их к контексту и соответственно установить их состояние:
Modified
, если FK должен быть установлен в ноль
Deleted
если Bar
следует удалить
Это все только для отношений один-ко-многим.
Если вы думали, что предыдущий подход сложен, будьте готовы к тому, что в случае независимой ассоциации (Bar
не имеет свойства FK - всегда имеет место для отношений многих ко многим), процесс еще хуже. Независимые ассоциации имеют свой собственный объект, отслеживающий состояние = установка состояния на Bar
сущность не сохраняет новые отношения. Первая проблема заключается в том, что этот объект не доступен напрямую из API DbContext - необходимо преобразовать DbContext
в ObjectContext
и использовать ObjectStateManager
, чтобы получить доступ к ObjectStateEntry
, представляющему отношение. После этого вы должны правильно установить его состояние, которое не так просто, как кажется, потому что отношение не может быть в состоянии Modified
- оно может быть только в Unchanged
, Added
или Deleted
. Это означает, что если вы изменили отношение Бар от одного к другому Foo
, вы должны сначала найти старое отношение и установить его как удаленное, а затем вы можете установить новое отношение как добавленное. Если у вас есть отношение «многие ко многим», и вы также хотите добавлять, удалять и обновлять связанные объекты (не только отношения), это может быть действительно «большим удовольствием» - особенно тот факт, что вы должны где-то хранить информацию, которая изменилась, чтобы быть возможность правильно установить все состояния.
Более подробное обсуждение этой проблемы (глобально в EF) - здесь - оно не связано с API DbContext, но поскольку новый API является просто оболочкой старого API ObjectContext, остаются те же проблемы.
Как вы думаете, это осуществимо? Я так не думаю. Из-за этого вы должны попытаться избежать этого. Есть несколько способов, как этого избежать:
- Вносить изменения в прикрепленный граф объектов - это означает, что сначала вы прикрепите исходное состояние графа сущностей к контексту, а затем внесете все свои изменения.
- Загрузить исходный граф объектов и вручную объединить все изменения из нового графика в загруженный (и прикрепленный).
- В случае ObjectContext API вы можете использовать Само-отслеживающиеся объекты , которые могут отслеживать состояние и автоматически устанавливать все, что применяется к контексту. У них есть некоторые другие недостатки и ограничения (например, они не поддерживают отложенную загрузку), и они недоступны для DbContext API.