如何修复将映射表映射到ViewModel的Automapper

时间:2019-04-23 14:53:30

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

我在ASP CORE 2项目中使用AutoMapper 7.0.1。我正在尝试用联接表映射一个类。从实体到我的视图模型的映射有效。当我ReverseMap()时,联接表为null,并且不映射回该实体。

其背后的原因是我使用viewModel获取一个int值列表,以将所选值填充到多选列表中。

我已经阅读过AutoMapper的文档,但是我必须在CreateMap配置中缺少某些内容。我尝试使用ForMember,但未成功。

我还试图了解ReverseMap()中的展平和展平过程

    //Article.cs

    public class Article
    {
        public int ArticleId { get; set; }
        public string Title { get; set; }
        public virtual ICollection<ArticleGroup> ArticleGroups { get; set; } = new List<ArticleGroup>();
    }

    //Group.cs

    public class Group
    {
       public int GroupId { get; set; }
       public string GroupName { get; set; }
       public virtual ICollection<ArticleGroup> ArticleGroups { get; set; } = new List<ArticleGroup>();
    }

    //ArticleGroup.cs

    public class ArticleGroup
    {
       public int ArticleId { get; set; }
       public Article Article { get; set; }
       public int GroupId { get; set; }
       public Group Group { get; set; }
    }

    //ArticleFormView.cs

    public class ArticleFormView
    {
        public int ArticleId { get; set; }
        public string Title { get; set; }
        public virtual List<int> GroupIds { get; set; }
    }

    //Startup.cs
    ...

    AutoMapper.Mapper.Initialize(cfg =>
    {
       cfg.CreateMap<Article, ArticleFormView>()
          .ReverseMap()
       ;

       //Tried this as well removing ReverseMap() from above
       //cfg.CreateMap<ArticleFormView, Article>()
       //    .ForMember(a => a.ArticleGroups, opt =>
       //        opt.MapFrom(src =>
       //            src.GroupIds
       //        )
       //    )
       //;
    });

    ...
//View Component
@model ArticleFormView

<div class="form-group">
    <label asp-for="Title" class="col-xs-1 control-label"></label>
    <div class="col-xs-11">
        <span asp-validation-for="Title" class="text-danger"></span>
        <input asp-for="Title" class="form-control">
    </div>
</div>
<div class="form-group">
    <label asp-for="GroupIds" class="col-xs-1 control-label"></label>
    <div class="col-xs-2">
        <select multiple="multiple" asp-for="GroupIds" asp-items="ViewBag.ListOfGroups" name="GroupIds[]" style="display:none"></select>
    </div>
</div>

如何将AutoMapper配置为从ViewModel中的int列表返回到Article实体中的ArticleGroup列表?

1 个答案:

答案 0 :(得分:1)

我试图重现您的情况,但最后我得到AutoMapperConfigurationException的声明,指出为GroupIds的{​​{1}}属性找到了未映射的成员。因此,我也从该域写了一张地图:

ArticleFormView

请注意,通过将文章中的实体映射到表单视图,您将不可避免地丢失数据。通过提供的表单视图结构,限制了在逆向映射过程中可以填写哪些成员的限制,这仅仅是因为您开始使用的数据较少。例如,仅保留组ID,就会丢失组名,因此在反转映射时,您将不知道组名。

Mapper.Initialize(cfg => { cfg.CreateMap<Article, ArticleFormView>() .ForMember(articleFormView => articleFormView.GroupIds, opts => opts.MapFrom(article => article.ArticleGroups.Select(articleGroup => articleGroup.GroupId))); cfg.CreateMap<ArticleFormView, Article>() .ForMember(article => article.ArticleGroups, opts => opts.MapFrom(articleFormView => articleFormView.GroupIds.Select(id => new ArticleGroup { // Uncomment these two lines if you need them. //Article = new Article { Title = articleFormView.Title, ArticleId = articleFormView.ArticleId }, //Group = new Group { GroupId = id }, ArticleId = articleFormView.ArticleId, GroupId = id, }))); }); 无法正常工作,因为AutoMapper无法自动知道如何对待两个不同类型和名称的不同集合:

  • ReverseMap():称为{em>“ ArticleGroups”
  • Article的集合
  • ArticleGroup:称为{em>“ GroupIds”
  • ArticleFormView列表