c# - 如何在子项上添加 where 子句并正确映射它

标签 c# entity-framework automapper

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

首先让我解释一下这个场景,我有一个 parent 和一个 child ,他们可以是活跃的也可以是不活跃的。如果父级不活动,则所有子级都不活动,如果父级事件,则某些子级可以是事件的,也可以是不活动的。 现在这将返回带有 child 的 parent

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

现在这就是我所追求的,只返回活跃的 parent 和活跃的 child

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();

最佳答案

旁注 - 如果您使用 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

关于c# - 如何在子项上添加 where 子句并正确映射它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43536918/

相关文章:

c# - Linq to Entities 4.0 是否具有全文功能?

c# - 在 C# 中遇到继承和泛型问题

c# - 将匿名类型作为 T 传递

automapper - Automapper:dto对象的自动 map 收集属性

c# - 是否可以告诉自动映射器在运行时忽略映射?

c# - WinForm richtextbox深度行间距和字符间距

C# 动态 MenuStrip(不接触窗体)

c# - 我应该将 Entity Framework 包含在我的类库中还是直接包含在应用程序中?

c# - 如果我在 Entity Framework 中全局禁用 ProxyCreation 会有什么后果?

c# - 关于 As<>() 方法在 AutoMapper 中的作用的详细信息