如何修复Automapper将连接表映射到ViewModel

问题描述 投票:1回答:1

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

其背后的原因是我使用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列表?

c# entity-framework asp.net-core automapper
1个回答
1
投票

我试图重现你的场景,我最终得到AutoMapperConfigurationException说明找到了GroupIdsArticleFormView属性的未映射成员。因此,我也从域中写了一张地图:

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

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

ReverseMap()不起作用,因为AutoMapper不会自动知道如何处理不同类型和名称的两个不同集合:

  • Article:一个名为“ArticleGroups”的ArticleGroup集合
  • ArticleFormView:一个名为“GroupIds”的int列表
© www.soinside.com 2019 - 2024. All rights reserved.