2011-09-28 13 views
18

actualmente estoy usando AutoMapper para trazar mis entidades de Entity Framework a mi punto de vista del modelo:ASP.net MVC - ¿Debo usar AutoMapper desde ViewModel a las entidades de 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); 
    } 
} 

Esto funciona bien. La pregunta que tengo es cuando necesito pasar de mi Modelo de Vista a mi entidad para actualizar la base de datos. ¿Debo usar AutoMapper para esto? ¿Es esta una mala/peligrosa práctica?

Parece que AutoMapper es bueno para aplanar un tipo complejo a un tipo simple (plano), pero hasta ahora estoy luchando tratando de pasar de un tipo plano/simple a uno más complejo como mi entidad con varios navegadores propiedades.

Si es una mala idea usar AutoMapper para hacer esto, ¿cómo se vería mi código para una acción de Crear?

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

¿Qué ocurre con una acción de edición?

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??? 
} 
+0

sus viewmodels pueden tener una propiedad de la entidad Producto, de esa manera no necesitará convertir nada. – Joakim

+0

Este artículo ofrece algunas sugerencias. http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/ – jrummell

Respuesta

25

Soy una de la mentalidad de que la actualización de sus entidades es un gran cosa y que ninguna herramienta automatizada nunca se debe utilizar. Establezca las propiedades manualmente.

Sí, es una cantidad muy pequeña de más código, pero el automapper o ejecutar el modelo de actualización en las entidades de bases de datos a veces puede tener consecuencias no deseadas. Es mejor asegurarse de que sus escrituras estén hechas correctamente.

+0

Estoy bien con esto, pero esto hace que mi controlador sea más feo. Soy de la opinión de que el controlador debe ser lo más simple posible (solo unas pocas líneas). ¿Debo aspirarlo? :) – Dismissile

+0

+1. Automapper y su tipo son geniales para aplanar entidades para ver modelos, pero necesita poner un poco más de pensamiento en la actualización de entidades. –

+4

@Dismissile - así que no coloque el código en el controlador. Cree una clase responsable de la conversión entre viewmodels y entidades, y llámela desde el controlador. Facilita las pruebas y se adhiere a SRP. –

10

Uso AutoMapper con una clase de mapeo especializada que comprende cómo hacer que un modelo complejo sea simple. AutoMapper se usa para manejar el mapeo de uno a uno y la lógica personalizada en la clase para hacer cosas más complejas (como relaciones, etc.). Toda la configuración de AutoMapper se realiza en el constructor estático para la clase de asignación, que también valida la configuración de asignación para que los errores fallen temprano.

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; 
    } 
} 
2

También puede probar la configuración de AutoMapper sólo a mapear las propiedades escalares (en lugar de tener que .Ignore() cada propiedad única que no lo quieren a (incluyendo propiedades heredadas como .EntityKey y .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 
      }); 
    }); 
Algunos

más información en http://www.prosoftnearshore.com/blog/post/2012/03/14/Using-AutoMapper-to-update-Entity-Framework-properties.aspx

0

Esencialmente automapping es malo, escribí un post sobre este http://blog.gavryli.uk/2015/12/02/why-automapping-is-bad-for-you/

+1

El enlace en la respuesta está roto, el nuevo parece ser https://ivanazure.wordpress.com/2015/12/02/ why-automapping-is-bad-for-you/ ¿Por qué todos los votos a favor? El artículo ofrece grandes argumentos en contra de la automatización. – Gebb

Cuestiones relacionadas