我对AutoMapper相当新。我很难配置AutoMapper,以便能够将UserViewModel
与多个TagViewModel
映射到实体框架核心所需的多对多关系(RecipeEntity <-> TagEntity
){{1是连接表。
数据对象:
UserAndTagEntity
测试示例:
public class TagEntity
{
public string Name { get; set; }
public virtual ICollection<UserAndTagEntity> UserAndTags { get; set; } = new List<UserAndTagEntity>();
}
public class UserEntity
{
public string Name { get; set; }
public virtual ICollection<UserAndTagEntity> UserAndTags { get; set; } = new List<UserAndTagEntity>();
}
public class UserAndTagEntity
{
public int Id { get; set; }
public virtual UserEntity User { get; set; }
public virtual TagEntity Tag { get; set; }
}
public class UserViewModel
{
public string Name { get; set; }
public IList<TagViewModel> Tags { get; set; }
}
public class TagViewModel
{
public string Name { get; set; }
}
这部分有效 - 我的问题是var config = new MapperConfiguration(cfg => {
cfg.CreateMap<UserEntity, UserViewModel>()
.ForMember(
dto => dto.Tags,
opt => opt.MapFrom(x => x.UserAndTags.Select(y => y.Tag)));
cfg.CreateMap<UserViewModel, UserEntity>()
.ForMember(
dto => dto.UserAndTags,
opt => opt.MapFrom(x => x.Tags))
.AfterMap((model, entity) =>
{
foreach (var entityUserAndTag in entity.UserAndTags)
{
entityUserAndTag.User = entity;
}
});
cfg.CreateMap<TagViewModel, UserAndTagEntity>();
});
var user = new UserViewModel()
{
Name = "User",
Tags = new List<TagViewModel>
{
new TagViewModel {Name = "Tag 1"},
new TagViewModel {Name = "Tag 2"},
new TagViewModel {Name = "Tag 3"},
new TagViewModel {Name = "Tag 4"},
}
};
IMapper mapper = config.CreateMapper();
var map = mapper.Map<UserViewModel, UserEntity>(user);
上的Tag
为空。
答案 0 :(得分:2)
可以使用以下配置实现从UserViewModel
到UserEntity
的映射:
CreateMap<UserViewModel, UserEntity>()
// (1)
.ForMember(entity => entity.UserAndTags, opt => opt.MapFrom(model => model.Tags))
// (5)
.AfterMap((model, entity) =>
{
foreach (var entityUserAndTag in entity.UserAndTags)
{
entityUserAndTag.User = entity;
}
});
// (2)
CreateMap<TagViewModel, UserAndTagEntity>()
// (3)
.ForMember(entity => entity.Tag, opt => opt.MapFrom(model => model));
// (4)
CreateMap<TagViewModel, TagEntity>();
<强>解释强>
需要第(1)行,因为目标和源属性名称不匹配,因此我们告诉AutoMapper将Tags
的{{1}}属性映射到{ {1}}的{1}}属性。
请注意,映射不要求源属性和目标属性 types 匹配。如果他们不这样做(如本例所示),AutoMapper将使用单独的配置映射它们。
在我们的示例中,源属性类型为UserViewModel
,目标属性类型为UserAndTags
。忽略集合类型 - AutoMapper知道如何转换它们。它不知道和需要指定的是元素类型之间的映射。在我们的案例中,从UserEntity
到IList<TagViewModel>
。因此需要映射(2)。
在映射(2)中,我们只有一个部分,所以我们使用(3)来指定 - 即我们将ICollection<UserAndTagEntity>
映射到TagViewModel
的{{1}}属性。类型再次不匹配,因此我们需要从UserAndTagEntity
到TagViewModel
的映射(4)。
所有这些最终结果将是Tag
实例,UserAndTagEntity
集合填充了TagViewModel
个具有正确TagEntity
属性的实例。然后,步骤(5)用于填充这些实例的UserEntity
属性。