2016-03-12 2 views
3

Подумайте о том, ViewModel:лучший способ проецирования ViewModel обратно в модель

public class ViewModel 
{ 
    public int id {get;set;} 
    public int a {get;set;} 
    public int b {get;set;} 
} 

и оригинальная модель, как это:

public class Model 
{ 
    public int id {get;set;} 
    public int a {get;set;} 
    public int b {get;set;} 
    public int c {get;set;} 
    public virtual Object d {get;set;} 
} 

Каждый раз, когда я получаю вид модели я должен поставить все свойства ViewModel один один в модель. Что-то вроде:

var model = Db.Models.Find(viewModel.Id); 
model.a = viewModel.a; 
model.b = viewModel.b; 
Db.SaveChanges(); 

Который всегда вызывает много проблем. Я даже иногда забываю упоминать некоторые свойства, а затем происходит катастрофа! Я искал что-то вроде:

Mapper.Map(model, viewModel); 

BTW: Я использую automapper только для преобразования модели в ViewModel, но в наоборот я всегда сталкиваюсь с ошибками.

+2

Если вы столкнулись с некоторыми проблемами с automapper затем разместить код, который используется для отображения моделей ViewModels. –

+0

Вы имеете в виду, что я могу использовать automapper в режиме vise versa? – ghazyy

+0

Мой опыт работы с automapper ограничен, но я уверен, что можно настроить, какие свойства должны быть сопоставлены и каким образом, чтобы вы могли игнорировать избыточные свойства или вычислять недостающие. –

ответ

8

В целом, что может быть не ответ, который вы ищете, но вот цитата из AutoMapper автора:

Я не могу за жизнь мне понять, почему я хочу, чтобы сбросить DTO прямо назад к объекту модели.

Я считаю, что лучший способ для отображения из ViewModel в Entity не использовать AutoMapper для этого. AutoMapper - отличный инструмент для использования при сопоставлении объектов без использования каких-либо других классов, кроме статических. В противном случае, код становится всё сложнее с каждой добавленной службой, и в каком-то момент вы не сможете отслеживать, что вызвало ваше обновление поля, обновление коллекции и т.д.

Конкретных вопросов часто сталкиваются:

  1. Необходимость создания нестатических классов для ваших объектов

    Возможно, вам придется использовать DbContext для загрузки и ссылки на объекты, вам также могут потребоваться другие классы - некоторый инструмент, который загружает изображения в хранилище файлов, статический класс, который делает хэширование/соль для пароля и т. д. и т. д. ... Вам либо нужно как-то передать его, чтобы автоматизировать, ввести или создать e внутри профиля AutoMapper, и обе практики довольно неприятны.

  2. Возможная потребность в нескольких отображений над одной ViewModel (DTO) -> Entity пар

    Вам может понадобиться различные отображения для одной пары ViewModel-объект, на основе, если этот объект представляет собой совокупность, или нет + на основе если вам нужно ссылаться на эту сущность или ссылку и обновление. В целом это разрешимо, но вызывает много ненужного шума в коде и еще сложнее поддерживать.

  3. Действительно грязный код, который трудно поддерживать.

    Это касается автоматического сопоставления для примитивов (строк, целых чисел и т. Д.) И ссылок на ручное сопоставление, преобразованных значений и т. Д. Код будет выглядеть действительно странным для automapper, вам нужно будет определить карты для свойств (или нет, если вы предпочитаете неявное сопоставление automapper, которое также разрушительно, если оно сопряжено с ORM) И используйте AfterMap, BeforeMap, Conventions, ConstructUsing и т. д. для сопоставления других свойств, что еще более усложняет работу.

  4. Комплексные отображения

    Когда приходится делать сложные отображения, как отображение из 2+ исходных классов до класса 1 назначения, вам придется усложнять вещи еще больше, вероятно, вызывающий код, как:

    var target = new Target(); 
    Mapper.Map(source1, target); 
    Mapper.Map(source2, target); 
    //etc.. 
    

    Этот код вызывает ошибки, поскольку вы не можете сопоставлять source1 и source2 вместе, и сопоставление может зависеть от порядка сопоставления исходных классов. И я не говорю, если вы забудете сделать 1 картографирование или если ваши карты имеют конфликтующие сопоставления над 1 свойством, переписывая друг друга.

Эти вопросы могут показаться незначительными, но на нескольких проектах, где я столкнулся использование Автоотображения библиотеки для отображения ViewModel/DTO к Сущности, это вызвало гораздо больше боли, чем если бы он никогда не был использован.

Вот некоторые ссылки для Вас:

2

Для этого мы написали простой картографа. Он отображает по имени и игнорирует виртуальные свойства (поэтому он работает с инфраструктурой сущности). Если вы хотите игнорировать определенные свойства, добавьте PropertyCopyIgnoreAttribute.

Использование:

PropertyCopy.Copy<ViewModel, Model>(vm, dbmodel); 
PropertyCopy.Copy<Model, ViewModel>(dbmodel, vm); 

Код:

public static class PropertyCopy 
{ 
    public static void Copy<TDest, TSource>(TDest destination, TSource source) 
     where TSource : class 
     where TDest : class 
    { 
     var destProperties = destination.GetType().GetProperties() 
      .Where(x => !x.CustomAttributes.Any(y => y.AttributeType.Name == PropertyCopyIgnoreAttribute.Name) && x.CanRead && x.CanWrite && !x.GetGetMethod().IsVirtual); 
     var sourceProperties = source.GetType().GetProperties() 
      .Where(x => !x.CustomAttributes.Any(y => y.AttributeType.Name == PropertyCopyIgnoreAttribute.Name) && x.CanRead && x.CanWrite && !x.GetGetMethod().IsVirtual); 
     var copyProperties = sourceProperties.Join(destProperties, x => x.Name, y => y.Name, (x, y) => x); 
     foreach (var sourceProperty in copyProperties) 
     { 
      var prop = destProperties.FirstOrDefault(x => x.Name == sourceProperty.Name); 
      prop.SetValue(destination, sourceProperty.GetValue(source)); 
     } 
    } 
} 
+0

Этот код работает для меня. «PropertyCopyIgnoreAttribute» выдает недопустимое ссылочное исключение, я удалил это для работы. В любом случае, спасибо за обмен. :) –

+0

@AndySchmitt Я считаю, что вы должны сами создать этот атрибут. – rbuddicom

+0

Нет, я просто думаю, что он забыл включить его :-) –

Смежные вопросы