Julie Lerman дает хороший способ справиться с тем, как обновить весь агрегат в своей книге Programming Entity Framework: DbContext.
Как она пишет:
Когда отключенный объект график поступает на стороне сервера, сервер не будет знать состояние субъектов. Вам необходимо предоставить способ для обнаружения состояния, чтобы контекст мог быть сделан , который знает состояние каждого объекта.
Этот метод называется painting the state
.
Есть в основном два способа сделать это:
- Итерация по графике, используя свои знания модели и установить состояние для каждого объекта
- Построить общий подход для отслеживания состояния
Второй вариант действительно приятный и состоит в создании интерфейса, который будет реализовывать каждый объект в вашей модели. Джули использует IObjectWithState
интерфейс, который говорит текущее состояние объекта:
public interface IObjectWithState
{
State State { get; set; }
}
public enum State
{
Added,
Unchanged,
Modified,
Deleted
}
Первое, что вам нужно сделать, это автоматически устанавливается Unchanged
каждые объекты, извлекаемые из базы данных за счет подключения событие, добавив конструктор в ваш Context
класс:
public YourContext()
{
((IObjectContextAdapter)this).ObjectContext
.ObjectMaterialized += (sender, args) =>
{
var entity = args.Entity as IObjectWithState;
if (entity != null)
{
entity.State = State.Unchanged;
}
};
}
Затем измените Order
и OrderItem
классов для реализации интерфейса IObjectWithState
и называют это ApplyChanges
метода принятия корневого объекта в качестве параметра:
private static void ApplyChanges<TEntity>(TEntity root)
where TEntity : class, IObjectWithState
{
using (var context = new YourContext())
{
context.Set<TEntity>().Add(root);
CheckForEntitiesWithoutStateInterface(context);
foreach (var entry in context.ChangeTracker
.Entries<IObjectWithState>())
{
IObjectWithState stateInfo = entry.Entity;
entry.State = ConvertState(stateInfo.State);
}
context.SaveChanges();
}
}
private static void CheckForEntitiesWithoutStateInterface(YourContext context)
{
var entitiesWithoutState =
from e in context.ChangeTracker.Entries()
where !(e.Entity is IObjectWithState)
select e;
if (entitiesWithoutState.Any())
{
throw new NotSupportedException("All entities must implement IObjectWithState");
}
}
И последнее, но не в последнюю очередь, не забудьте установить правильное состояние вашего графа entites перед вызовом ApplyChanges
;-) (можно даже смешивать Modified
и Deleted
состояний в одном графике)
Джули предлагает ищите еще больше в своей книге:
Вы можете обнаружить, что хотите быть более зернистым с помощью способа Отслеживаются измененные свойства. Вместо того, чтобы маркировать весь объект с изменениями, возможно, вам понадобятся только те свойства, которые на самом деле , были помечены как измененные. В дополнение к маркировке объекта, модифицированного, клиент также является , ответственным за запись свойств, которые были изменены. Один из способов: сделать это - добавить список измененных имен свойств в интерфейс отслеживания состояния .
Но мой ответ уже слишком долго, почитайте ее book если вы хотите узнать больше ;-)
Существует предложение, чтобы добавить лучшую поддержку отслеживания изменений с графиками - https: //entityframework.codeplex.com/workitem/864 и там есть ссылка на graphdiff, которая может помочь – Colin