Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.net MVC-我应该在ViewModel到实体框架实体之间使用AutoMapper吗?_C#_Asp.net Mvc_Entity Framework_Automapper - Fatal编程技术网

C# ASP.net MVC-我应该在ViewModel到实体框架实体之间使用AutoMapper吗?

C# ASP.net MVC-我应该在ViewModel到实体框架实体之间使用AutoMapper吗?,c#,asp.net-mvc,entity-framework,automapper,C#,Asp.net Mvc,Entity Framework,Automapper,我目前正在使用AutoMapper将实体框架实体映射到视图模型: public class ProductsController : Controller { private IProductRepository productRepository; public ProductsController(IProductRepository productRepository) { this.productRepository = productRepo

我目前正在使用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);
    }
}
编辑操作怎么样

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???
}

我的思维方式是更新实体是一件非常重要的事情,不应该使用任何自动化工具。手动设置属性


是的,这只需要非常少量的代码,但是automapper或在数据库实体上运行updatemodel有时会产生意想不到的后果。最好确保您的写入操作正确。

我将AutoMapper与一个专门的映射类一起使用,该类了解如何从简单模型生成复杂模型。AutoMapper用于处理类中的一对一映射和自定义逻辑,以完成更复杂的事情(如关系等)。所有的AutoMapper配置都是在mapping类的静态构造函数中完成的,该类还验证了mapping配置,因此错误会提前失败

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;
    }
}
公共类模型映射器
{
静态模型映射器()
{
Mapper.CreateMap()
.ForMember(f=>f.bar,opt=>opt.Ignore());
assertConfigurationsValid();
}
公共Foo CreateFromModel(FooView模型,IEnumerable条)
{
var foo=Mapper.Map();
foreach(model.barId中的var barId)
{
foo.bar.Add(bar.Single(b=>b.Id==barId));
}
返回foo;
}
}

您还可以尝试将AutoMapper配置为仅映射标量属性(而不必映射
.Ignore()
您不希望映射的每个属性(包括继承的属性,如
.EntityKey
.EntityState

AutoMapper.Mapper.CreateMap()
.对于所有成员(o=>{
o、 条件(ctx=>
{
var members=ctx.Parent.SourceType.GetMember(ctx.MemberName);//获取我们映射的MemberInfo
如果(!members.Any())
返回false;
返回members.First().GetCustomAttributes(typeof(EdmScalarPropertyAttribute),false)。Any();//确定该成员是否设置了EdmScalar属性
});
});

更多信息请访问

自动映射本质上是不好的,我在这篇文章上写了一篇博文

你的viewmodels可以拥有实体产品的属性,这样你就根本不需要转换。这篇文章提供了一些建议。我同意这一点,但这会让我的控制器变得丑陋不堪。我的心态是控制器应该具备的尽可能地简单(只有几行长)。我应该把它吸起来吗?:)@Dismissile-所以不要把代码放在控制器中。创建一个负责在viewmodels和实体之间转换的类,并从控制器调用该类。使测试更容易,并遵守SRP。您知道,您可以自定义映射,以完全按照您希望它为每个属性执行的操作。我看不出这和你自己写作业陈述有什么区别。对于简单的属性到属性映射,我认为它工作得很好。+1到jfar。告诉我不要问。使用automapper就是问你是否问我。还要尽可能地保持简单,并尽可能多地消除框架依赖关系。@tvanfosson-这比编写
Model.Property=ViewModel.Property所需的秒数还要多。
答案中的链接断了,新的链接似乎是为什么所有人都投反对票的原因?这篇文章给出了反对自动映射的有力论据。从另一个角度来看自动映射的缩减,不要担心缩减投票。我建议在你的回答中包括你的一些观点。
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;
    }
}
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
            });
    });