AutoMapper多对多关系收集 [英] AutoMapper many to many relationship into collection

查看:112
本文介绍了AutoMapper多对多关系收集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆