2012-08-02 87 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