Подтвердить что ты не робот

ASP.net MVC. Должен ли я использовать AutoMapper из объектов ViewModel для Entity Framework?

В настоящее время я использую AutoMapper для сопоставления сущностей Entity Framework с моей моделью просмотра:

public class ProductsController : Controller
{
    private IProductRepository productRepository;

    public ProductsController(IProductRepository productRepository)
    {
         this.productRepository = productRepository;
    }

    public ActionResult Details(int id)
    {
        var product = productRepository.GetProduct(id);

        if( product == null )
            return View("NotFound");

        ProductDetailsViewModel model = Mapper.Map<Product, ProductDetailsViewModel>(product);

        return View(model);
    }
}

Это хорошо работает. У меня есть вопрос, когда мне нужно перейти от моей модели просмотра к моей сущности, чтобы обновить базу данных. Должен ли я использовать AutoMapper для этого? Является ли это плохой/опасной практикой?

Кажется, что AutoMapper хорош для сглаживания сложного типа простым (плоским) типом, но до сих пор я изо всех сил стараюсь перейти от простого/простого к более сложному типу, например, моего объекта с различными свойствами навигации.

Если это плохая идея использовать AutoMapper для этого, то как бы выглядел мой код для действия Create?

public ActionResult Create(CreateProductViewModel model)
{
    if( ModelState.IsValid )
    {
        // what do i do here to create my Product entity?
    }
}

Как насчет действия "Изменить"?

public ActionResult Edit(int id, EditProductViewModel model)
{
    Product product = productRepository.GetProduct(id);

    // how do i convert my view model to my entity at this point???
}
4b9b3361

Ответ 1

Я считаю, что обновление ваших сущностей - это довольно крупная сделка и что ни один автоматизированный инструмент никогда не будет использоваться. Задайте свойства вручную.

Да, его очень малая часть большего количества кода, но automapper или running updatemodel на объектах базы данных иногда могут иметь непреднамеренные последствия. Лучше убедиться, что ваши записи выполнены правильно.

Ответ 2

Я использую AutoMapper со специализированным классом сопоставления, который понимает, как сделать сложную модель из простой. AutoMapper используется для обработки сопоставления "один-к-одному" и пользовательской логики в классе для выполнения более сложных действий (таких как отношения и т.д.). Вся конфигурация AutoMapper выполняется в статическом конструкторе для класса сопоставления, который также проверяет конфигурацию отображения, чтобы ошибки не выполнялись раньше.

public class ModelMapper
{
    static ModelMapper()
    {
        Mapper.CreateMap<FooView,Foo>()
              .ForMember( f => f.Bars, opt => opt.Ignore() );

        Mapper.AssertConfigurationIsValid();
    }

    public Foo CreateFromModel( FooView model, IEnumerable<Bar> bars )
    {
         var foo = Mapper.Map<FooView,Foo>();
         foreach (var barId in model.BarIds)
         {
             foo.Bars.Add( bars.Single( b => b.Id == barId ) );
         }
         return foo;
    }
}

Ответ 3

Вы также можете попробовать настроить AutoMapper только для отображения свойств Scalar (вместо того, чтобы иметь .Ignore() каждое отдельное свойство, которое вы не хотите (включая унаследованные свойства, такие как .EntityKey и .EntityState).

AutoMapper.Mapper.CreateMap<EntityType, EntityType>()
    .ForAllMembers(o => {
         o.Condition(ctx =>
             {
                 var members = ctx.Parent.SourceType.GetMember(ctx.MemberName); // get the MemberInfo that we are mapping

                if (!members.Any())
                    return false;
                return members.First().GetCustomAttributes(typeof(EdmScalarPropertyAttribute), false).Any(); // determine if the Member has the EdmScalar attribute set
            });
    });

Дополнительная информация на http://www.prosoftnearshore.com/blog/post/2012/03/14/Using-AutoMapper-to-update-Entity-Framework-properties.aspx