【问题标题】:Is there a way to map from a list to a scalar property using auto mapper?有没有办法使用自动映射器从列表映射到标量属性?
【发布时间】:2020-03-06 14:28:55
【问题描述】:

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

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

这对数据库很有效,并且在业务规则发生变化的情况下提供了未来的灵活性。

这一切正常,但我发现自己在业务层中手动映射 PrimaryChild 和 SecondaryChild 属性,而其他所有内容都由 automapper 映射。

有没有办法指示 automapper 进行这种映射?我没有运气找到遵循这种结构的示例。

【问题讨论】:

    标签: c# .net-core automapper


    【解决方案1】:

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

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

    • 应该映射到列表中的属性
    • 应该如何设置 IsPrimary 标志,具体取决于它是哪些属性
    • (对于双向绑定)应该将哪个列表元素映射到哪个属性

    举一个简单的例子来说明它的复杂程度:如果您的列表有几个孩子,但 none 被标记为主要怎么办?你怎么会隐含地知道该怎么做?

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

    这将是一大堆代码,并没有真正为库的功能增加价值。

    【讨论】:

    • 这是我的怀疑,但我想我会提出这个问题,以防有更好的方法来做到这一点。我打算暂时搁置这个问题,看看是否有人有更好的解决方案,但我认为你是对的。
    • 至于没有设置IsPrimary标志的情况,我不允许。对业务层和 DAL 进行检查以防止这种情况发生。有人需要手动进入数据库并导致该问题。如果确实遇到这种情况,我当前的映射将把它找到的第一条记录作为主要记录。
    • @Jesse “如果确实遇到这种情况,我当前的映射将把它找到的第一个记录作为主要记录。” 这是第四个要点:改变IsPrimary 标志值基于列表的所有元素中都没有值。这也是一个如此定制的逻辑示例,以至于无法合理抽象(同时通过抽象提供实际好处)
    • 澄清一下,我并不期望它是自动的,但我认为由于它在技术上是映射代码,因此它在映射配置文件中的位置可能比在业务层中的位置更好。
    【解决方案2】:

    嗯,它可以通过以下方式完成:

    .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 的集合,这样您就可以得到一个可以处理数据不一致的直接映射,之后您可以根据需要对其进行过滤。

    【讨论】:

    • 这是一个有趣的想法。我试图让我的业务层对象的结构反映业务规则,但我想我没有理由不能存储列表并实现逻辑来从父类中过滤和公开这些属性,而不是直接映射。谢谢。我可能会选择这个。
    • 将为根据需要调整 BLL 逻辑和处理错误提供更多空间。
    猜你喜欢
    • 1970-01-01
    • 2019-01-13
    • 2011-02-02
    • 1970-01-01
    • 2021-09-15
    • 1970-01-01
    • 2021-10-28
    • 2017-10-02
    • 1970-01-01
    相关资源
    最近更新 更多