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

时间:2011-09-28 20:02:03

标签: c# asp.net-mvc entity-framework automapper

我目前正在使用AutoMapper将我的实体框架实体映射到我的视图模型:

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

这很有效。我的问题是当我需要从我的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???
}

4 个答案:

答案 0 :(得分:27)

我有一种心态,即更新您的实体是非常重要,并且不应该使用任何自动化工具。手动设置属性。

是的,它的代码数量非常少,但是在数据库实体上自动化或运行updatemodel有时会产生意想不到的后果。最好确保您的写入正确完成。

答案 1 :(得分: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;
    }
}

答案 2 :(得分:2)

您还可以尝试将AutoMapper配置为仅映射标量属性(而不是每个您不希望它的属性.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
            });
    });

http://www.prosoftnearshore.com/blog/post/2012/03/14/Using-AutoMapper-to-update-Entity-Framework-properties.aspx

的更多信息

答案 3 :(得分:1)

基本上自动化很糟糕,我写了一篇关于这个http://blog.gavryli.uk/2015/12/02/why-automapping-is-bad-for-you/

的博客文章