2011-09-28 5 views
18

私は現在、私のビューモデルに私のEntity FrameworkのエンティティをマッピングするためにAutoMapperを使用しています:ASP.net MVC - ViewModelから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??? 
} 
+0

あなたのビューモデルはエンティティプロダクトのプロパティを持つことができます。変換する必要はありません。 – Joakim

+0

この記事にはいくつかの提案があります。 http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/ – jrummell

答えて

25

私はあなたのエンティティを更新するかなり大したであること、および自動化ツールは、これまで使用してはならないという考え方のです。プロパティを手動で設定します。

はい、そのコードは非常に少量ですが、データベースエンティティ上の自動マッパーまたは実行中のupdatemodelは意図しない結果を招くことがあります。あなたの書き込みが正しく行われていることを確認することをお勧めします。

+0

私はこれでいいですが、この種の私のコントローラは醜いことを超えています。コントローラはできるだけシンプルでなければならない(わずか数行ですむ)という考え方があります。私はそれを吸うべきですか? :) – Dismissile

+0

+1。 Automapperとそのilkは、エンティティをビューモデルに展開するのに最適ですが、エンティティを更新するにはもう少し考えなくてはなりません。 –

+4

@Dismissile - コントローラにコードを入れないでください。ビューモデルとエンティティの間の変換を行うクラスを作成し、それをコントローラから呼び出します。テストを簡単にし、SRPを遵守します。 –

10

私はAutoMapperを、複雑なモデルを単純なものから作る方法を理解している特殊なマッピングクラスを使っています。 AutoMapperは、より複雑なもの(関係など)を行うために、1対1のマッピングとカスタムロジックをクラス内で処理するために使用されます。 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; 
    } 
} 
2

また、唯一の代わりに.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 
      }); 
    }); 
にAutoMapperを設定してみてください

さらに詳しい情報:http://www.prosoftnearshore.com/blog/post/2012/03/14/Using-AutoMapper-to-update-Entity-Framework-properties.aspx

0

本物のオートキャリングは悪いです、私はこのブログの投稿を書いたhttp://blog.gavryli.uk/2015/12/02/why-automapping-is-bad-for-you/

+1

答えのリンクが壊れています。新しいリンクはhttps://ivanazure.wordpress.com/2015/12/02/のようですあなたがなぜ悪いのですか?/ なぜすべてのdownvotes?この記事では、オートキャッピングに対する大きな議論がなされています。 – Gebb

関連する問題