SOK*_*SOK 2 c# entity-framework automapper entity-framework-core
我对 AutoMapper 还很陌生。我很难将 AutoMapper 配置为能够将UserViewModel多个映射TagViewModel为多对多关系 ( RecipeEntity <-> TagEntity),这是 Entity Framework Core 所需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; }
}
Run Code Online (Sandbox Code Playgroud)
测试示例:
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);
Run Code Online (Sandbox Code Playgroud)
这部分有效 - 我的问题是TagonUserAndTagEntity为空。
从UserViewModelto的映射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>();
Run Code Online (Sandbox Code Playgroud)
解释:
需要线(1),因为目标和源属性名称不匹配,所以我们只是告诉AutoMapper映射Tags的财产UserViewModel来UserAndTags的财产UserEntity。
请注意,映射不要求源和目标属性类型匹配。如果没有(如本例),AutoMapper 将使用单独的配置映射它们。
在我们的例子中,源属性类型是IList<TagViewModel>,目标属性类型是ICollection<UserAndTagEntity>。忽略集合类型 - AutoMapper 知道如何转换它们。它不知道并且需要指定的是元素类型之间的映射。在我们的例子中,从TagViewModel到UserAndTagEntity。因此需要映射(2)。
在映射 (2) 中,我们只有一个部分,因此我们使用 (3) 来指定 - 即我们映射TagViewModel到 的Tag属性UserAndTagEntity。类型再次不匹配,因此我们需要从TagViewModel到的映射(4)TagEntity。
所有这些最终结果将是具有正确属性的UserEntity实例的UserAndTags集合。然后使用步骤(5)来填充这些实例的属性。UserAndTagEntityTagUser
| 归档时间: |
|
| 查看次数: |
4303 次 |
| 最近记录: |