【问题标题】:How to add a where clause on children and map it properly如何在孩子上添加 where 子句并正确映射
【发布时间】:2017-04-21 07:49:40
【问题描述】:

在 EF 获取数据并使用 Automapper 进行映射时,如何对子项运行查询?

让我先解释一下这个场景,我有一个父母和一个孩子,他们可以是活跃的或不活跃的。如果父母不活动,那么所有孩子都不活动,如果父母活动,那么一些孩子可以是活动的或不活动的。 现在这将返回带有孩子的父母

return Mapper.Instance.Map<ObservableCollection<Parent>>(context.Parent.AsNoTracking().ProjectTo<ParentDTOWithChildren>(Mapper.Configuration));

现在这就是我所追求的,只返回活跃的父母和活跃的孩子

Mapper.Instance.Map<ObservableCollection<Parent>>(context.Parent.AsNoTracking()
      .Where(p => p.IsInactive != true)
      .Select(parent => new
      {
          parent,
          Children = parent.Children.Where(c => c.IsInactive != true)
      })
      .ProjectTo<ParentDTOWithChildren>(Mapper.Configuration));

第二次尝试生成正确的 sql 查询,但是映射没有正确映射,子级获取所有值,但父级没有。 我发现如果我手动选择每个属性,则父级会获取所有属性,所以这是可行的

Mapper.Instance.Map<ObservableCollection<Parent>>(context.Parent.AsNoTracking()
      .Where(p => p.IsInactive != true)
      .Select(parent => new
      {
         parent.Id,
         parent.Description,
         parent.Information,
         . . . 
         Children = parent.Children.Where(c => c.IsInactive != true)
     })
     .ProjectTo<ParentDTOWithChildren>(Mapper.Configuration));

理想情况下,我只想选择父级(使用中间的示例),它应该知道如何映射它,但直到我指定了我想要的每个属性时它才知道。映射配置正确完成,因为第一个示例工作得很好,有没有更好的方法从该匿名类型中选择(映射​​)所有属性到我的 DTO ?

非常感谢。

编辑

这就是让它工作而不是选择匿名类型的原因

获取数据的服务。

Mapper.Instance.Map<ObservableCollection<Parent>>
(context.Parent.AsNoTracking().Where(p => p.IsInactive != true)
.ProjectTo<ParentDTOWithChildren>(Mapper.Configuration, new {excludeInactive = true}));

映射

var excludeInactive = false;
CreateMap<Parent, ParentDTOWithChildren>()
.ForMember(p => p.Children, opt => opt.MapFrom(parent => parent.Children.Where(child  => !excludeInactive || child.IsInactive != true)))
.ReverseMap();

【问题讨论】:

  • 发布示例类和 AM 配置可能会有所帮助。

标签: c# entity-framework automapper


【解决方案1】:

旁注 - 如果您使用 AutoMapper 的静态实例,请去掉“Mapper.Instance”以及传入“Mapper.Configuration”的位置。这些都是多余的。

对于您最初的问题 - 不。但是,您可以映射到代表您的匿名类型的中间类型“ParentWithChildren”,因此它看起来像:

Mapper.Map<ObservableCollection<Parent>>(context.Parent.AsNoTracking()
  .Where(p => p.IsInactive != true)
  .Select(p => Mapper.Map<ParentWithChild>(p))
 .ProjectTo<ParentDTOWithChildren>());

您的 Parent -> ParentWithNoChildren 配置将包含该 Children 片段作为 MapFrom 配置。

一般来说,我不是映射到匿名类型,而是创建一个显式类型(即使 EF 不知道它),映射到它,然后执行任何其他映射:

EF类型->中间模型->DTO

【讨论】:

  • 感谢您的回复,我发现我根本不需要使用匿名类型(或者中间模型,我尝试过但它抛出了异常)。当我引起你的注意时,你能看看我的编辑,看看我的解决方案是否有任何潜在的危险?感谢您的旁注,这些多余的参数很快就会被删除。
  • 编辑有意义!
猜你喜欢
  • 2020-11-14
  • 1970-01-01
  • 1970-01-01
  • 2012-01-21
  • 1970-01-01
  • 2012-06-13
  • 2011-09-15
  • 2016-12-16
  • 2013-12-23
相关资源
最近更新 更多