【问题标题】:Using automapper to apply a filter to a collection使用 automapper 将过滤器应用于集合
【发布时间】:2011-09-07 18:12:25
【问题描述】:

我有一个包含集合的域模型,我想使用 AutoMapper 将父级和子级映射到视图模型,但我不希望被“软”删除的子级被删除。例如:

public class Customer {
   public EntitySet<Order> {get;set;}
}
public class Order {
   public DateTime? DeletedDate {get;set;}
}

我的 AutoMapper 定义是

Mapper.CreateMap<Customer, CustomerViewModel>();
Mapper.CreateMap<Order, OrderViewModel>();

而且我不希望订单出现在具有 DeletedDate 值的视图模型中。

这在 AutoMapper 中可行吗?提前非常感谢,

史蒂夫。

【问题讨论】:

    标签: filter collections automapper


    【解决方案1】:

    我遇到了类似的问题,最后类似于下面的方法对我有用:

    Mapper.CreateMap<Customer, CustomerViewModel>()
        .ForMember(dest => dest.Orders, 
            opt => opt.MapFrom(src => src.Orders.Where(o => !o.DeletedDate.HasValue)));
    

    这假定您的 Customer 实体和 CustomerViewModel 具有名为“Orders”的集合。

    【讨论】:

    • 如果我们需要添加一个变量,我们该怎么做。前任。 Where(o=&gt;o.UserId== variableUserId)?
    【解决方案2】:

    这听起来很适合custom ValueResolver。它将允许您以孤立的方式进行逻辑检查。我现在没有 Visual Studio,但如果你愿意,我可以稍后添加一些示例代码。

    编辑: 在对此进行修补之后,我认为 ValueResolver 不是要走的路。我能够通过为Order 映射使用以下条件配置来使其工作:

    Mapper.CreateMap<Order, OrderViewModel>()
       .ForAllMembers(opt => opt.Condition(src => !src.DeletedDate.HasValue));
    

    唯一的问题是OrderViewModel仍然会出现,但它会是null。换句话说,如果您有 3 个订单,其中一个有删除日期,那么您的视图模型中的订单数量仍将是 3,但删除的值将是 null。我猜最好只有 2 个,但我现在还没有明确的方法来做到这一点。

    Here's a post 来自 AutoMapper 的作者的回复,其中谈到了 Skip 方法,但我无法在我正在使用的最新版本中看到该功能。

    【讨论】:

    • 您会将 ValueResolver 应用于 Customer 还是 Order 的地图?
    • 嗨,我也看到了作者 Jimmy Bogard 的那篇文章,并尝试使用 Skip 扩展方法,但未能成功。由于该帖子的发布日期为 2010 年 4 月,因此可能随后被删除?
    • 也许这个问题的答案是 Automapper 真的只是一个映射工具,不应该用来做某种业务领域逻辑。例如,展平结构是可以的,但忽略从集合中转换某些成员是不行的。由于 MVC 视图应该非常愚蠢,因此我不愿意遍历 Order 集合并跳过 null 或具有 DeletedDate 集的那些。同样,我不确定在 CustomerViewModel 上放置一个名为 GetOrdersNotDeleted 的新方法的纯度。
    • @stevie_c:你说得很好。 AutoMapper 确实将基于约定的映射应用于源方法——以Get* 开头的方法将映射到目标(视图模型)中的相应属性。在这种情况下,您可以在读取 GetActiveOrders() 的域对象上创建一个方法,并拥有一个视图模型属性 ActiveOrders,这应该在没有任何额外配置的情况下映射。
    • 谢谢,这是个好主意。我需要考虑一下,因为我的域类实际上是一个 Linq2Sql 实体。所以我可以添加GetActiveOrders(),它执行类似return Orders.Where(x =&gt; x.RemovedDate == null) 的操作,但这会使该方法无法测试(目前对我而言),因为域类使用的是Sql 数据上下文。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-05
    • 1970-01-01
    • 2018-12-08
    相关资源
    最近更新 更多