2011-09-28 25 views
18

Tôi hiện đang sử dụng để lập bản đồ AutoMapper Entity Framework đơn vị của tôi để xem mẫu của tôi:ASP.net MVC - Tôi có nên sử dụng AutoMapper từ các đối tượng ViewModel đến Entity Framework không?

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

này hoạt động tốt. Câu hỏi mà tôi có là khi tôi cần phải đi từ Mô hình Xem của mình đến thực thể của tôi để cập nhật cơ sở dữ liệu. Tôi có nên sử dụng AutoMapper cho việc này không? Đây có phải là một thực hành xấu/nguy hiểm không? Có vẻ như AutoMapper là tốt cho việc làm phẳng một loại phức tạp thành một kiểu đơn giản (phẳng), nhưng cho đến nay tôi đang cố gắng chuyển từ kiểu đơn giản sang kiểu phức tạp hơn như thực thể của tôi với các điều hướng khác nhau tính chất.

Nếu bạn sử dụng AutoMapper để làm điều này, thì mã của tôi sẽ trông như thế nào đối với hành động Tạo?

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

Điều gì về hành động Chỉnh sửa?

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

mô hình chế độ xem của bạn có thể có thuộc tính của sản phẩm thực thể, theo cách đó bạn sẽ không cần phải chuyển đổi chút nào. – Joakim

+0

Bài viết này cung cấp một vài gợi ý. http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/ – jrummell

Trả lời

25

tôi là một trong những suy nghĩ rằng việc cập nhật các đối tượng của bạn là một việc khá lớn và rằng không có công cụ tự động bao giờ nên được sử dụng. Đặt các thuộc tính theo cách thủ công.

Có số lượng mã rất nhỏ nhưng tự động hóa hoặc chạy updatemodel trên các thực thể cơ sở dữ liệu đôi khi có thể có hậu quả không mong muốn. Tốt hơn để đảm bảo viết của bạn được thực hiện một cách chính xác.

+0

Tôi ổn với điều này, nhưng loại này làm cho bộ điều khiển của tôi vượt quá xấu xí. Tôi nghĩ rằng bộ điều khiển nên đơn giản nhất có thể (chỉ một vài dòng dài). Tôi có nên hút nó lên không? :) – Dismissile

+0

+1. Automapper và ilk của nó là tuyệt vời cho các thực thể phẳng để xem mô hình, nhưng bạn cần phải đặt một chút suy nghĩ vào việc cập nhật các thực thể. –

+4

@Dismissile - do đó, không đặt mã trong bộ điều khiển. Tạo một lớp chịu trách nhiệm chuyển đổi giữa các mô hình và các thực thể, và gọi nó từ bộ điều khiển. Làm cho thử nghiệm dễ dàng hơn và tuân thủ SRP. –

10

Tôi sử dụng AutoMapper với lớp ánh xạ chuyên biệt để hiểu cách tạo mô hình phức tạp từ mô hình đơn giản. AutoMapper được sử dụng để xử lý ánh xạ một-một và logic tùy chỉnh trong lớp để thực hiện những điều phức tạp hơn (như các mối quan hệ, v.v.). Tất cả cấu hình AutoMapper được thực hiện trong hàm dựng tĩnh cho lớp ánh xạ, nó cũng xác thực cấu hình ánh xạ để các lỗi bị lỗi sớm.

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

Bạn cũng có thể thử cấu hình AutoMapper để chỉ bản đồ thuộc tính vô hướng (thay vì phải .Ignore() mỗi tài sản duy nhất bạn không muốn nó (bao gồm cả tài sản thừa kế như .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 
      }); 
    }); 

một số thêm thông tin tại http://www.prosoftnearshore.com/blog/post/2012/03/14/Using-AutoMapper-to-update-Entity-Framework-properties.aspx

0

về cơ bản automapping là xấu, tôi đã viết một bài đăng blog về vấn đề này http://blog.gavryli.uk/2015/12/02/why-automapping-is-bad-for-you/

+1

Liên kết trong câu trả lời bị hỏng, cách mới có vẻ là https://ivanazure.wordpress.com/2015/12/02/ Tại sao-automapping-là-xấu-cho-bạn/ Tại sao tất cả các downvotes? Bài viết đưa ra các đối số tuyệt vời chống lại việc tự động hóa. – Gebb

Các vấn đề liên quan