2012-08-02 58 views
5

我试图通过使用AutoMapper多对多的表映射实体到一个集合。AutoMapper多对多关系到集合

我的域模型(实体框架)看起来是这样的:

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; } 
} 

我试图映射到一个类,它看起来像这样:

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; } 
} 

我目前的映射配置看起来是这样的:

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,但当我尝试执行盟友将用户映射到UserDTO,我得到:正文的签名和方法实现中的声明不匹配。

如果我使用AfterMap并将每个公司手动移动到公司列表中,它将起作用,但似乎我应该能够在创建地图中处理此问题。

在我的查询从数据库中获取单个用户我包括UserCompany.Company导航属性,我可以quickwatch,看到有返回。

回答

6

您不需要在映射配置中具有显式映射。你应该能够做这样的事情:

Mapper.CreateMap<User, UserDTO>() 
    .ForMember(dto => dto.Companies, opt => opt.MapFrom(x => x.UserCompanies)); 

您还需要定义UserCompany的映射:

Mapper.CreateMap<UserCompany, CompanyDTO>(); 

请注意,你不必在你的例子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(); 

哪里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(); 
    } 
} 
+0

我想你的建议,但结果是一样的。 UserCompany是一个连接User和Company的实体,因此为了将UserCompany映射到公司,我必须明确映射每个字段,即 Mapper.CreateMap () .ForMember(dto => dto.Name,opt => opt.MapFrom(x => x.Company.Name); 除此之外,尝试删除我的公司对象的IList映射和我仍然看到相同的错误 – 2012-08-02 21:39:39

+0

另外尝试切换我的MapTo到这个:.ForMember(dto => dto.Companies,opt => opt.MapFrom(x => x.UserCompanies)),同样的错误 – 2012-08-02 21:44:43

+0

Mighty,我明白了。我不认为这是值得一提的,但我映射到的Dto对象实际上是接口类型。 AutoMapper试图为其创建代理对象时发生错误。我的原始映射代码工作正常,将此行添加到映射设置。 感谢您的帮助! – 2012-08-02 22:53:55