[英]AutoMapper: One-to-many -> Many-to-many
我是AutoMapper的新手。 我也很难配置AutoMapper在能够映射UserViewModel
具有多个TagViewModel
成许多一对多关系( RecipeEntity <-> TagEntity
这是所需要的实体框架的核心,其中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
上UserAndTagEntity
为空。
使用以下配置可以实现从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
的财产UserViewModel
到UserAndTags
的财产UserEntity
。
请注意,映射不需要源属性和目标属性类型匹配。 如果没有(在这种情况下),则AutoMapper将使用单独的配置映射它们。
在我们的示例中,源属性类型为IList<TagViewModel>
,目标属性类型为ICollection<UserAndTagEntity>
。 忽略集合类型-AutoMapper知道如何转换它们。 它不知道并且需要指定的是元素类型之间的映射。 在我们的例子中,从TagViewModel
到UserAndTagEntity
。 因此,需要映射(2)。
里面的映射(2),我们只有部分之一,所以我们使用(3)指定-即我们映射TagViewModel
到Tag
的财产UserAndTagEntity
。 同样,类型不匹配,因此我们需要从TagViewModel
到TagEntity
的映射(4)。
最终结果将是带有UserAndTags
集合的UserEntity
实例, UserAndTags
填充了具有正确Tag
属性的UserAndTagEntity
实例。 然后,使用步骤(5)填充这些实例的User
属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.