2011-09-28 8 views
18

Attualmente sto usando automapper per mappare i miei soggetti Entity Framework alla mia vista Modello:ASP.net MVC - Devo utilizzare AutoMapper da ViewModel alle entità 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); 
    } 
} 

Questo metodo funziona bene. La domanda che ho è quando devo andare dal mio View Model alla mia entità per aggiornare il database. Dovrei usare AutoMapper per questo? È una pratica cattiva/pericolosa?

Sembra AutoMapper è buono per appiattire un tipo complesso a un tipo (piatto) semplice, ma finora sto lottando cercando di passare da un tipo semplice/piatto a un tipo più complesso come la mia entità con le varie navigazione proprietà.

Se è una cattiva idea utilizzare AutoMapper per fare ciò, quale sarebbe il mio codice per un'azione Crea?

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

E un'azione di modifica?

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

i tuoi viewmodels potrebbero avere una proprietà del prodotto dell'entità, in questo modo non avrai bisogno di convertire affatto. – Joakim

+0

Questo articolo offre alcuni suggerimenti. http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/ – jrummell

risposta

25

Sono una della mentalità che aggiornare i entità è un abbastanza grosso problema e che nessuno strumento automatico dovrebbe mai essere utilizzato. Impostare le proprietà manualmente.

Sì, si tratta di una quantità molto piccola di codice in più, ma l'automapper o l'esecuzione di updatemodel su entità di database possono talvolta avere conseguenze indesiderate. È meglio assicurarsi che le tue scritture siano fatte correttamente.

+0

Sto bene con questo, ma questo tipo rende il mio controller oltre il brutto. Sono del parere che il controller dovrebbe essere il più semplice possibile (solo poche righe). Dovrei solo succhiarlo? :) – Dismissile

+0

+1. Automapper e il suo tipo sono ottimi per appiattire le entità sui viewmodels, ma è necessario pensare un po 'più all'aggiornamento delle entità. –

+4

@Dismissile - quindi non inserire il codice nel controller. Crea una classe responsabile della conversione tra viewmodels ed entità e chiamala dal controller. Rende più semplice il test e aderisce a SRP. –

10

Uso AutoMapper con una classe di mapping specializzata che comprende come realizzare un modello complesso da uno semplice. AutoMapper è usato per gestire il mapping one-to-one e la logica personalizzata nella classe per eseguire le cose più complesse (come le relazioni, ecc.). Tutta la configurazione di AutoMapper viene eseguita nel costruttore statico per la classe di mapping, che inoltre convalida la configurazione di mapping in modo che gli errori non vengano eseguiti in anticipo.

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

Si potrebbe anche provare a configurare automapper per mappare solo le proprietà scalari (invece di dover .Ignore() ogni singola proprietà non si vuole che (incluse le proprietà ereditate come .EntityKey e .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 
      }); 
    }); 

qualche info in più a http://www.prosoftnearshore.com/blog/post/2012/03/14/Using-AutoMapper-to-update-Entity-Framework-properties.aspx

0

Essenzialmente automapping è male, ho scritto un post sul blog su questo http://blog.gavryli.uk/2015/12/02/why-automapping-is-bad-for-you/

+1

Il collegamento nella risposta è interrotto, il nuovo sembra essere https://ivanazure.wordpress.com/2015/12/02/ why-automapping-is-bad-for-you/ Perché tutti i downvotes? L'articolo offre grandi argomenti contro l'automapping. – Gebb

Problemi correlati