6

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

次のようなクラスにマップしようとしています。

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を使用して、各会社を手動で会社リストに移動すると、機能しますが、マップの作成内でこれを処理できるはずです。

DBから単一のユーザーを取得するためのクエリに、UserCompany.Companyナビゲーションプロパティを含めています。クイックウォッチして、返されるものがあることを確認できます。

4

1 に答える 1

8

マッピング構成に明示的なマップを含める必要はありません。次のようなことができるはずです。

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

UserCompanyのマッピングも定義する必要があります。

Mapper.CreateMap<UserCompany, CompanyDTO>();

例にはCompanyDTOクラスが含まれていないため、実際のマッピング構成を判別できないことに注意してください。

アップデート

単なるIListではなく、Userエンティティに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();
    }
}
于 2012-08-02T19:12:14.300 に答える