有没有一种方法可以使用自动映射器从列表映射到标量属性?

时间:2020-03-06 14:28:55

标签: c# .net-core automapper

在我的业务层中,我有以下对象

class ParentClass
{
    // Parent class properties
    ChildClass PrimaryChild { get; set; }
    ChildClass SecondaryClass { get; set; }
}

class ChildClass
{
    //Child class properties
}

业务规则规定只有一个主要和次要孩子

在DAL中,尽管将其设置为标准的一对多关系很有意义

class ParentEntity
{
    // Parent properties
    IEnumerable<ChildEntity> Children { get; set; }
}

class ChildEntity
{
    // Child properties

    bool IsPrimary { get; set; }

    int ParentId { get; set; }
    ParentEntity Parent { get; set; }
}

这对数据库都很好,并且在业务规则确实发生更改的情况下提供了未来的灵活性。

这一切都很好,但是我发现自己在业务层中手动映射了PrimaryChildSecondaryChild属性,而其他所有内容都由自动映射器映射。

有没有一种方法可以指示automapper进行这种映射?找到符合这种结构的示例并没有运气。

2 个答案:

答案 0 :(得分:2)

据我所知,这不能隐式完成。

即使存在隐式执行此功能的能力,它也需要您明确指出:

  • 应映射到列表中的属性
  • 如何根据其属性设置IsPrimary标志
  • (用于双向绑定)哪个列表元素应映射到哪个属性

举一个简单的例子,说明它可能有多复杂:如果您的列表中有几个子代,但一个却被标记为主要子代,该怎么办?您将如何隐式知道该怎么办?

一旦您已经准备好编写这些自定义的逻辑部分,您基本上就已经重写了整个手动映射,并且除了执行手动编写的步骤之外,框架实际上不会做很多事情。

很多代码并没有真正为库的功能增加价值。

答案 1 :(得分:1)

可以用类似的方法完成

.ForMember(dest => dest.PrimaryChild ,
            opt => opt.MapFrom(src => src.Children.FirstOrDefault(c => c.IsPrimary)))

.ForMember(dest => dest.SecondaryClass,
            opt => opt.MapFrom(src => src.Children.FirstOrDefault(c => !c.IsPrimary)))

但是它依赖于源数据与您对它的解释方式一致,并且依赖于在映射点设置的IsPrimary属性。

在可行的情况下,最好更改ParentClass以容纳ChildClass的集合,这样您将获得一个直接映射,该映射将处理数据不一致的情况,然后可以根据需要进行过滤。