Automapper - 将多对多关联映射到平面对象的最佳实践

Posted

技术标签:

【中文标题】Automapper - 将多对多关联映射到平面对象的最佳实践【英文标题】:Automapper - Bestpractice of mapping a many-to-many association into a flat object 【发布时间】:2011-04-11 07:30:31 【问题描述】:

我有两个实体:EmployeeTeam

我想要的是一个具有NameTeamEmployeeForm

如何使用 AutoMapper 实现这一点?

我目前的“解决方案”如下:

Mapper.CreateMap<Employee, EmployeeForm>()
                           .ForMember(dest => dest.TeamName, opt => opt.MapFrom(x => x.GetTeams().FirstOrDefault() != null ? string.Join(", ", x.GetTeams().Select(y=>y.Name)) : "n/a"));

在我看来,这很难读。

我想要的是一个通用方法,我可以在其中传递一个实体,选择集合并说如果集合为空,则返回默认值,或者通过 lambda 表达式选择集合的属性。

【问题讨论】:

【参考方案1】:

您可以在 Employee 上创建一个名为“TeamNames”的只读字符串属性。将列表构建逻辑放在那里。这样一来,您就有了一个可测试的属性(相对于 lambda 表达式),这将使您的映射更容易。

【讨论】:

你的想法听起来不错,我稍后会试试这个=) @Patrick,您的解决方案没有帮助。您将有重复的条目。因此,拥有两个团队的员工将显示两次。您可以区分列表,但是当分页起作用时,您会遇到问题。总计数不正确,行号也不正确。我试图回答我的问题,请随时查看。 不确定您如何查看生成的重复条目(除非您允许将员工多次添加到同一个团队)。我只是提倡一个名为 Employee.TeamNames 的字符串属性(它使用您现有的 lambda 表达式来构建)并将 EmployeeForm.Team 更改为 EmployeeForm.TeamNames 以便自动映射器加入它们而无需任何自定义映射。 是的,我允许在多个团队中拥有一名员工 是的,我确实理解了您的建议。但正如我所说,一名员工可能是多个团队的成员。这会导致重复。你可以用 .Distinct() 解决这个问题,但是如果你想分页,你会遇到麻烦,因为行号错误。【参考方案2】:

我重新思考了我的整个设计,开始改变领域模型

我使用关系表将many-to-many association 更改为两个one-to-many associations

有了这个更简单的域模型,我可以使用AutoMapper轻松地将它映射到一个平面DTO

public class TeamEmployeeMapperProfile : Profile

    protected override void Configure()
    
        CreateMap<TeamEmployee, TeamEmployeeForm>();
    

是的,就是这样:)

这是平面视图模型对象。

【讨论】:

如果这对你有用,那很好。但是,我不确定我是否愿意更改我的域模型,以便更轻松地与其他一些实用程序/库集成。 是的,看起来是这样,但事实并非如此。在我看来,这是一个普遍的问题。多对多关联太难处理了。我使用 NHibernate 和现在使用 AutoMapper 获得了这种体验。但正如我所说,这不是工具的问题,而是关联本身的问题。

以上是关于Automapper - 将多对多关联映射到平面对象的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate学习笔记 --- 创建基于中间关联表的多对多映射关系

hibernate多对多关联映射

一口一口吃掉Hibernate——多对多关联映射

关联映射 ---- Hibernate之多对多关系

Hibernate多表关系配置——多对多对关系映射

Hibernate映射( 多对一对一对多多对多)的配置方法