C# 自动映射:一对多->;多对多
我是汽车制造商的新手。我很难将AutoMapper配置为能够将具有多个C# 自动映射:一对多->;多对多,c#,entity-framework,automapper,entity-framework-core,C#,Entity Framework,Automapper,Entity Framework Core,我是汽车制造商的新手。我很难将AutoMapper配置为能够将具有多个TagViewModel的UserViewModel映射到多对多关系(RecipeEntity TagEntity)中,这是实体框架核心所需的,UserAndTagEntity是连接表 数据对象: public class TagEntity { public string Name { get; set; } public virtual ICollection<UserAndTagEntity>
TagViewModel
的UserViewModel
映射到多对多关系(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; }
}
公共类标记实体
{
公共字符串名称{get;set;}
公共虚拟ICollection UserAndTags{get;set;}=new List();
}
公共类用户实体
{
公共字符串名称{get;set;}
公共虚拟ICollection UserAndTags{get;set;}=new List();
}
公共类UserAndTagEntity
{
公共int Id{get;set;}
公共虚拟用户实体用户{get;set;}
公共虚拟标记实体标记{get;set;}
}
公共类UserViewModel
{
公共字符串名称{get;set;}
公共IList标记{get;set;}
}
公共类TagViewModel
{
公共字符串名称{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);
var config=new-MapperConfiguration(cfg=>{
cfg.CreateMap()
福门博先生(
dto=>dto.Tags,
opt=>opt.MapFrom(x=>x.UserAndTags.Select(y=>y.Tag));
cfg.CreateMap()
福门博先生(
dto=>dto.UserAndTags,
opt=>opt.MapFrom(x=>x.Tags))
.AfterMap((模型、实体)=>
{
foreach(entity.UserAndTags中的var entityUserAndTag)
{
entityUserAndTag.User=实体;
}
});
CreateMap();
});
var user=new UserViewModel()
{
Name=“User”,
标签=新列表
{
新的TagViewModel{Name=“Tag 1”},
新的TagViewModel{Name=“Tag 2”},
新的TagViewModel{Name=“Tag 3”},
新的TagViewModel{Name=“Tag 4”},
}
};
IMapper mapper=config.CreateMapper();
var map=mapper.map(用户);
这在一定程度上起作用-我遇到的问题是
UserAndTagEntity
上的Tag
为空。可以通过以下配置实现从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>();
CreateMap()
// (1)
.ForMember(entity=>entity.UserAndTags,opt=>opt.MapFrom(model=>model.Tags))
// (5)
.AfterMap((模型、实体)=>
{
foreach(entity.UserAndTags中的var entityUserAndTag)
{
entityUserAndTag.User=实体;
}
});
// (2)
CreateMap()
// (3)
.ForMember(entity=>entity.Tag,opt=>opt.MapFrom(model=>model));
// (4)
CreateMap();
说明:
需要行(1),因为目标和源属性名称不匹配,所以我们只需要告诉AutoMapper将UserViewModel的Tags
属性映射到UserEntity的UserAndTags
属性
请注意,映射不要求源和目标属性类型匹配。如果它们没有(如本例中所示),AutoMapper将使用单独的配置映射它们
在我们的例子中,源属性类型是IList
,目标属性类型是ICollection
。忽略集合类型-AutoMapper知道如何转换它们。它不知道并且需要指定的是元素类型之间的映射。在我们的例子中,从TagViewModel
到UserAndTagEntity
。因此需要映射(2)
在映射(2)中,我们只有一个部分,因此我们使用(3)指定-即,我们将TagViewModel
映射到UserAndTagEntity
的Tag
属性。同样,类型不匹配,因此我们需要从TagViewModel
到TagEntity
的映射(4)
最后的结果将是UserEntity
实例和UserAndTags
集合,集合中填充了UserAndTagEntity
实例和正确的Tag
属性。然后使用步骤(5)填充这些实例的User
属性。可以通过以下配置实现从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>();
CreateMap()
// (1)
.ForMember(entity=>entity.UserAndTags,opt=>opt.MapFrom(model=>model.Tags))
// (5)
.AfterMap((模型、实体)=>
{
foreach(entity.UserAndTags中的var entityUserAndTag)
{
entityUserAndTag.User=实体;
}
});
// (2)
CreateMap()
// (3)
.ForMember(entity=>entity.Tag,opt=>opt.MapFrom(model=>model));
// (4)
CreateMap();
说明:
需要行(1),因为目标和源属性名称不匹配,所以我们只需要告诉AutoMapper将UserViewModel的Tags
属性映射到UserEntity的UserAndTags
属性
请注意,映射不要求源和目标属性类型匹配。如果它们没有(如本例中所示),AutoMapper将使用单独的配置映射它们
在我们的例子中,源属性类型是IList
,目标属性类型是ICollection
。忽略集合类型-AutoMapper知道如何转换它们。它不知道并且需要指定的是元素类型之间的映射。在我们的例子中,从TagViewModel
到UserAndTagEntity
。因此需要映射(2)
在映射(2)中,我们只有一个部分,因此我们使用(3)指定-即,我们将TagViewModel
映射到UserAndTagEntity
的Tag
属性。同样,类型不匹配,因此我们需要从TagViewModel
到TagEntity
的映射(4)
最后的结果将是UserEntity
实例和UserAndTags
集合,集合中填充了UserAndTagEntity
实例和正确的Tag