Совокупная корневая поддержка в Entity Framework
Как мы можем сказать Entity Framework о Агрегатах?
- при сохранении совокупности сохраняйте сущности в совокупности
- при удалении агрегата удалите сущности внутри агрегата
- поднять ошибку concurrency, когда два разных пользователя пытаются изменить два разных объекта внутри одного и того же aggreate
- при загрузке агрегата, обеспечивайте согласованное представление времени агрегата по времени, даже если есть некоторая временная задержка до того, как мы получим доступ ко всем сущностям в совокупности
(сначала Entity Framework 4.3.1 Code)
Ответы
Ответ 1
EF предоставляет функции, которые позволяют вам определять свои агрегаты и использовать их:
- Это самая болезненная часть. EF работает с графами сущностей. Если у вас есть объект, такой как счет-фактура, и у этого объекта есть коллекция связанных объектов InvoiceLine, вы можете обращаться к нему как к агрегату. Если вы находитесь в подключенном сценарии, все работает так, как ожидалось, но в отключенном сценарии (либо агрегат не загружается EF, либо загружается другим экземпляром контекста), вы должны прикрепить экземпляр aggregate к экземпляру контекста и точно сказать, что вы изменили = установить состояние для каждой сущности и независимой ассоциации в графе объектов.
- Это выполняется с помощью каскадного удаления - если у вас есть связанные объекты загружены, EF удалит их, но если вы этого не сделаете, вы должны иметь каскадное удаление, настроенное для отношения в базе данных.
- В базе данных используются токены concurrency - чаще всего столбцы с меткой времени или столбцом строки.
- Вы должны либо использовать загрузку и загрузку всех данных в начале (= согласованная точка зрения), либо использовать ленивую загрузку, и в этом случае у вас не будет постоянной точки зрения, потому что ленивая загрузка будет загружать текущее состояние но он не будет обновлять другие части агрегата, которые вы уже загрузили (и я считаю это убийцей производительности, если вы пытаетесь реализовать такое обновление с помощью EF).
Ответ 2
Я написал GraphDiff специально для этой цели. Это позволяет вам определить "совокупную границу" при обновлении путем обеспечения плавного отображения. Я использовал его в тех случаях, когда мне нужно было передавать отдельные графы объектов взад и вперед.
Например:
// Update method of repository
public void Update(Order order)
{
context.UpdateGraph(order, map => map
.OwnedCollection(p => p.OrderItems);
}
Выше было бы сообщить Entity Framework обновить сущность заказа, а также объединить коллекцию OrderItems. Отображение таким образом позволяет нам гарантировать, что Entity Framework управляет только графом в пределах, которые мы определяем в совокупности, и игнорирует все другие свойства. Он поддерживает оптимизацию concurrency проверки всех объектов. Он обрабатывает гораздо более сложные сценарии и может также обрабатывать ссылки на ссылки во многих сценариях (через AssociatedCollections).
Надеюсь, что это может быть полезно.