我在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列表?
我试图重现你的场景,我最终得到AutoMapperConfigurationException
说明找到了GroupIds
的ArticleFormView
属性的未映射成员。因此,我也从域中写了一张地图:
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
列表