У меня есть следующая проблема (высокий уровень): My ViewModel имеет некоторые свойства, которые могут быть отредактированы пользователем (в моем представлении). Большинство свойств напрямую привязаны к моей модели Entity Framework. Во многих ситуациях это приводит к тому, что мне приходится отделять мою модель e. г. после сохранения его в базу данных (если я этого не сделаю, и пользователь внесет некоторые изменения в представление, эти изменения будут автоматически отражаться при вызове следующего SaveChanges()
). Отключение его, к сожалению, приводит к тому, что все виртуальные свойства становятся нулевыми. Поэтому я должен убедиться, что создаю надлежащие «копии» моего объекта, прежде чем отсоединять его. Это приводит к множеству побочных эффектов.Побочные эффекты, если ViewModel напрямую привязан к Model of Entity Framework
Чтобы дать Вам лучшее понимание моей проблемы некоторые примеры кода (конечно упрощенных):
Моя модель:
public class Child
{
public int SomeNumber { get; set; }
public string SomeText { get; set; }
public int MotherId { get; set; }
public virtual Mother Mother { get; set; }
public virtual ICollection<Sibling> Siblings { get; set; }
}
Мой ViewModel:
public class ChildViewModel : ViewModel
{
private IGenericRepository<Child> _repository;
public string SomeText
{
get { return MyModel.SomeText; }
set
{
MyModel.SomeText = value;
RaisePropertyChanged("SomeText");
}
}
public Mother Mother
{
get { return MyModel.Mother; }
set
{
MyModel.Mother = value;
RaisePropertyChanged("Mother");
}
}
public void Save()
{
if (MyModel.Id == 0)
{
Insert();
}
else
{
Update();
}
UnitOfWork.Save();
_repository.Detach(PrimaryModel);
}
}
Как вы можете увидеть, что свойства ViewModel напрямую привязаны к моей модели EF. В «Сохранить» мне нужно отсоединиться после сохранения. Если я этого не делаю, это приведет к следующей проблеме: пользователь меняет SomeText
в представлении, но не сохраняет. Теперь вызывается UnitOfWork.Save()
. Измененное значение SomeText
случайно сохраняется. Побочным эффектом этого является то, что свойство Mother теперь будет null.
Чтобы избежать этой ситуации, я попытался создать «реальные» копии моего объекта. Поэтому каждая модель должна реализовать метод для копирования своих значений. Это становится сложным и подверженным ошибкам, когда речь идет о сложных объектах. При попытке сохранить «скопированный» объект у меня есть еще больше побочных эффектов, таких как ошибка Attaching an entity of type ... failed because another entity of the same type already has the same primary key value.
(особенно с «скопированными» 1: многие и многие: многие объекты).
Резюме:
- непосредственно связывать модели через ViewModel к представлению ...
- ... может привести к некоторым побочным эффектам, когда не отделяя его.
- Отсоединение модели приводит к виртуальным свойствам, которые становятся нулевыми.
- Чтобы избежать этого, копия объекта может быть создана до отсоединения.
- Трудно сохранить скопированные объекты, когда они очень сложны (несколько отношений 1: многие и многие: многие).
Это приводит к проблемам, которые облегчают использование (например, «Сохранить набор данных xyz») - по крайней мере, они должны быть легко imo - стоить много времени, а код становится все более сложным.
Как я могу избежать этих подводных камней?
Наше решение состоит в том, что мы используем объекты модели только как чистые DTO. Мы извлекаем их из EF, наполняем наши собственные объекты и не позволяем им уходить. То же самое для сохранения. Создавайте новые DTO, присоединяйте, заполняйте их и сохраняйте. – Andre
Я думал о том же. Для этого потребуется дополнительный уровень (уровень обслуживания или так), который не будет проблемой. – mosquito87
Вы (мы, у меня такая же проблема) также можем оценить карту, которая отображает из ViewModel в Model (перед сохранением). Ты подумал? – bubi