AutoMapper多对多关系收集 [英] AutoMapper many to many relationship into collection
问题描述
我正在尝试使用AutoMapper通过多对多表将实体映射到集合中.
I'm trying to map entities into a collection through a many to many table using AutoMapper.
我的域模型(实体框架)如下:
My domain model (Entity Framework) looks like this:
public class User
{
public int UserID { get; set; }
public string Name { get; set; }
public IList<UserCompany> UserCompanies { get; set; }
}
public class Company
{
public int CompanyID { get; set; }
public string Name { get; set; }
}
public class UserCompany
{
public int UserCompanyID { get; set; }
public int UserID { get; set; }
public int CompanyID { get; set; }
}
我正在尝试映射到如下所示的类:
I'm trying to map to a class that looks like this:
public class CompanyDTO
{
public int CompanyID { get; set; }
public string Name { get; set; }
}
public class UserDTO
{
public int UserID { get; set; }
public string Name { get; set; }
public IList<CompanyDTO> Companies { get; set; }
}
我当前的映射配置如下:
My current mapping configuration looks like this:
Mapper.CreateMap<Company, CompanyDTO>(); //works no problem
Mapper.CreateMap<User, UserDTO>()
.ForMember( dto => dto.Companies,
opt => opt.MapFrom(x => Mapper.Map<IList<Company>, IList<CompanyDTO>>(x.UserCompanies.Select( y => y.Company ).ToList())));
断言配置有效会返回true,但是当我尝试将User实际映射到UserDTO时,会得到:主体的签名和方法实现中的声明不匹配.
Asserting that the configuration is valid returns true, but when I try to actually map a User to a UserDTO, I get: Signature of the body and declaration in a method implementation do not match.
如果我使用AfterMap并手动将每个公司移到公司"列表中,则可以使用,但是看来我应该能够在创建地图中进行处理.
If I use AfterMap and manually move over each Company into the Companies list, it will work, but it seems like I should be able to handle this within create map.
在要从数据库中获取单个用户的查询中,我包括UserCompany.Company导航属性,并且可以快速观察并看到返回了.
In my query to get a single user from the DB I am including the UserCompany.Company navigation property and I can quickwatch and see that there is being returned.
推荐答案
您不需要在映射配置中具有显式映射.您应该能够执行以下操作:
You don't need to have the explicit map in your mapping configuration. You should be able to do something like:
Mapper.CreateMap<User, UserDTO>()
.ForMember(dto => dto.Companies, opt => opt.MapFrom(x => x.UserCompanies));
您还需要为UserCompany定义一个映射:
You'll also need to define a mapping for UserCompany:
Mapper.CreateMap<UserCompany, CompanyDTO>();
请注意,您的示例中没有CompanyDTO类,因此我无法确定实际的映射配置.
Note that you don't have a CompanyDTO class in your examples so I can't determine the actual mapping configuration.
更新
我认为有一个原因,为什么您需要在User实体中使用一个IList而不是一个IList.鉴于此,我相信您需要一个自定义解析程序: https://github.com/AutoMapper/AutoMapper/wiki/自定义值解析器
I presume there is a reason why you need an IList in your User entity rather than simply an IList. Given that, I believe you need a custom resolver: https://github.com/AutoMapper/AutoMapper/wiki/Custom-value-resolvers
更新2
很高兴您能对它进行排序.为了完整起见,这里是您决定将自定义ValueResolver与上述类一起使用的示例.
I'm glad you have it sorted. For completeness, heres the example should you decide to use a custom ValueResolver with the classes above.
Mapper.CreateMap<Company, CompanyDTO>();
Mapper.CreateMap<User, UserDTO>()
.ForMember(dto => dto.Companies, opt => opt.ResolveUsing<CompanyResolver>());
Mapper.AssertConfigurationIsValid();
CompanyResolver类似于
Where CompanyResolver is something like
public class CompanyResolver : ValueResolver<User, IList<CompanyDTO>>
{
protected override IList<CompanyDTO> ResolveCore(User source)
{
return source.UserCompanies
.Select(userCompany =>
Mapper.Map<Company, CompanyDTO>(companies.FirstOrDefault(x => x.CompanyID == userCompany.CompanyID)))
.ToList();
}
}
这篇关于AutoMapper多对多关系收集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!