AutoMapper 多对多关系转化为集合

标签 automapper

我正在尝试使用 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,但是当我尝试将 User 实际映射到 UserDTO 时,我得到:方法实现中的主体签名和声明不匹配。

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

在我从数据库获取单个用户的查询中,我包含了 UserCompany.Company 导航属性,我可以快速查看并查看正在返回的内容。

最佳答案

您不需要在映射配置中具有显式映射。您应该能够执行以下操作:

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

关于AutoMapper 多对多关系转化为集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11782948/

相关文章:

caSTLe-windsor - CaSTLe Windsor 更新后无法解析 AutoMapper 配置文件

asp.net-mvc - 使用 Automapper 映射列表

c# - Automapper 将 Flags Enum 从 ViewModel 映射到域模型

c# - .net 中的对象复制方法 : Auto Mapper, Emit Mapper、隐式操作、属性复制

c# - 使用 MVC3 中的存储库模式和 Entity Framework 将域模型转换为 ViewModel 并再次返回

c# - AutoMapper:领域模型和 View 模型之间的双向深度映射

c# - Automapper 5.0.0 缺少 SourceValue(自定义转换器)

entity-framework - 为什么 automapper 使 Entity Framework 插入而不是更新?

c# - 自动映射器创建新实例而不是映射属性

c# - 无法在 Autofac 中注册和添加自动映射器配置文件