ASP.net MVC - 我应该使用ViewModel中的AutoMapper到Entity Framework实体吗?

Dis*_*ile 21 c# asp.net-mvc entity-framework automapper

我目前正在使用AutoMapper将我的Entity Framework实体映射到我的View Model:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这很好用.我的问题是当我需要从我的View Model转到我的实体以更新数据库时.我应该使用AutoMapper吗?这是一个糟糕/危险的做法吗?

似乎AutoMapper很适合将复杂类型展平为简单(平面)类型,但到目前为止,我正在努力尝试从平面/简单到更复杂的类型,如我的实体具有各种导航属性.

如果使用AutoMapper执行此操作是个坏主意,那么我的代码对于Create操作会是什么样子?

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

编辑动作怎么样?

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???
}
Run Code Online (Sandbox Code Playgroud)

Joh*_*ell 28

我是一个更新实体的心态,这是一个非常重要的事情,不应该使用任何自动化工具.手动设置属性.

是的,它只是一小部分代码,但是自动化或在数据库实体上运行updatemodel有时会产生意想不到的后果.最好确保您的写入正确完成.

  • 您知道可以自定义映射以完全按照您希望的方式为每个属性执行操作.我并没有真正看到它与编写自己的赋值语句之间的区别.对于简单的属性到属性映射,我认为它运行良好. (10认同)
  • @Dismissile - 所以不要把代码放在控制器中.创建一个负责在视图模型和实体之间进行转换的类,并从控制器中调用它.使测试更容易并坚持SRP. (4认同)
  • +1到jfar.告诉不要问.使用automapper问你是否问我.同时保持尽可能简单,并尽可能多地发布框架依赖关系. (3认同)

tva*_*son 12

我使用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;
    }
}
Run Code Online (Sandbox Code Playgroud)