AutoMapper:如何仅映射匹配的属性名称而忽略所有其他属性?

时间:2018-05-04 14:19:43

标签: c# automapper automapper-6

我是AutoMapper的新手并使用版本6.2.2。我正在尝试将视图模型映射到实体(也使用实体框架)。我想只更新viewmodel和实体中存在的属性。该实体具有其他导航属性和不属于源视图模型的相关对象。我目前收到一个错误,我在目标实体上有未映射的属性。我的viewmodel和entity都有超过40个属性,因此我不想将每个属性显式添加到地图中。

这是我的代码:

地图:

public static void RegisterMaps()
{
    AutoMapper.Mapper.Initialize(config =>
    {
                    config.CreateMap<EditApplicationViewModel, Application>();

    });

}

我也尝试过以下操作但得到同样的错误:

config.CreateMap<EditApplicationViewModel, Application>(MemberList.source);

控制器:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(EditApplicationViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        Application application = _applicationService.GetById(viewModel.ApplicationId);

        application = Mapper.Map(viewModel, application);
    }
}

错误讯息:

  

的InnerException:          的HResult = -2146233088          消息=找到未映射的成员。查看下面的类型和成员。添加自定义映射表达式,忽略,添加自定义   解析器,或修改源/目标类型无匹配   构造函数,添加无参数ctor,添加可选参数或映射全部   构造函数参数   ================================================== ========字符串 - &gt;用户(目标成员列表)System.String - &gt;    。***。entities.User(目标会员列表)

     

未映射的属性: 已删除 - 一个很长的相关对象列表   和目的地的属性

   Source=AutoMapper
   StackTrace:
        at lambda_method(Closure , EditApplicationViewModel , Application , ResolutionContext )

更新

我也试过以下地图。我没有收到任何错误,但没有任何源属性在目标上更新。

config.CreateMap<EditApplicationViewModel, Application>().ForAllOtherMembers(opts=>opts.Ignore());

3 个答案:

答案 0 :(得分:3)

我能够解决我的问题,它与忽略源和目标之间不匹配的属性无关。看来默认情况下,AutoMapper的默认行为已经忽略了这些属性。

错误信息非常具有欺骗性:

  InnerException: 
       HResult=-2146233088
       Message=
Unmapped members were found. Review the types and members below.
Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type
For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters
==========================================================
String -> User (Destination member list)
System.String -> ***.***.***.entities.User (Destination member list)

我的问题的实际原因是类型不匹配。我在视图模型中有一个名为CreatedByUser的字符串属性。我的实体上也有一个名为CreatedByUser的导航属性,类型为User。

我必须在CreateMap中明确忽略此属性。

 config.CreateMap<EditApplicationViewModel, Application>()
                    .ForMember(d => d.CreatedByUser, opt => opt.Ignore());

不需要其他指令来忽略在源或目的地上不存在的任何其他属性。

同样,我收到的错误消息&#34;未找到成员的成员被发现。&#34;通过我。实际问题是类型不匹配。

答案 1 :(得分:0)

您可以使用IgnoreUnMapped()函数。

          config.CreateMap<EditApplicationViewModel, Application>().IgnoreUnMapped();

答案 2 :(得分:0)

两个模型中的所有属性可能都没有相同的名称。对于不同的名称属性,您可以使用以下示例:

var source = new Source();

void ConfigureMap(IMappingOperationOptions<Source, Dest> opt) {
    opt.ConfigureMap()
       .ForMember(dest => dest.Value, m => m.MapFrom(src => src.Value))
};

var dest = Mapper.Map<Source, Dest>(source, ConfigureMap);

每个新的媒体资源名称不匹配,您定义新的.ForMember...