我正在尝试使用AutoMapper通过多对多表将实体映射到集合中.
我的域模型(Entity Framework)如下所示:
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; }
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试映射到看起来像这样的类:
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; }
}
Run Code Online (Sandbox Code Playgroud)
我当前的映射配置如下所示:
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())));
Run Code Online (Sandbox Code Playgroud)
断言配置有效返回true,但是当我尝试将User实际映射到UserDTO时,我得到:正文的签名和方法实现中的声明不匹配.
如果我使用AfterMap并手动将每个公司移动到公司列表中,它将起作用,但似乎我应该能够在创建地图中处理这个问题.
在我从DB获取单个用户的查询中,我包含了UserCompany.Company导航属性,我可以快速观察并查看是否有返回.
您不需要在映射配置中具有显式映射.你应该可以这样做:
Mapper.CreateMap<User, UserDTO>()
.ForMember(dto => dto.Companies, opt => opt.MapFrom(x => x.UserCompanies));
Run Code Online (Sandbox Code Playgroud)
您还需要为UserCompany定义映射:
Mapper.CreateMap<UserCompany, CompanyDTO>();
Run Code Online (Sandbox Code Playgroud)
请注意,示例中没有CompanyDTO类,因此无法确定实际的映射配置.
更新
我认为你的用户实体中需要一个IList而不仅仅是一个IList是有原因的.鉴于此,我相信你需要一个自定义解析器:https://github.com/AutoMapper/AutoMapper/wiki/Custom-value-resolvers
更新2
我很高兴你把它整理好了.为了完整性,下面是示例,您应该决定使用上面的类的自定义ValueResolver.
Mapper.CreateMap<Company, CompanyDTO>();
Mapper.CreateMap<User, UserDTO>()
.ForMember(dto => dto.Companies, opt => opt.ResolveUsing<CompanyResolver>());
Mapper.AssertConfigurationIsValid();
Run Code Online (Sandbox Code Playgroud)
CompanyResolver就是这样的
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();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5540 次 |
| 最近记录: |