【问题标题】:Linq to Entities, select parent entities with child entities, where child entities match condtionLinq to Entities,选择有子实体的父实体,子实体匹配条件
【发布时间】:2018-11-10 01:19:43
【问题描述】:

这似乎应该是一件简单的事情,但我似乎无法找到一个可以满足我需要的示例。

我有实体“Person”和“SavedSearch”。这些与外键正确连接,因此导航属性有效。一个“Person”可以包含多个“SavedSearch”实体。

我想要做的是选择所有“Person”实体的列表,每个实体都有一个“SavedSearch”实体的集合,这些 SavedSearch 实体满足特定条件。

这是我能得到的最接近的...

Dim person_query = From p In db.Person
                   Where p.SavedSearch.Any(Function(s) s.SendEmails = True)
                   Select New SavedSearchDetails With {
                     .PersonID = p.PersonID,
                     .SavedSearchList = p.SavedSearch.Where(Function(s) s.SendEmails = True)
                   }

这给了我正确的结果,但是必须两次指定 where 条件似乎是不正确的。检查生成的 SQL,我可以看到它使用了左外连接,我认为这不是必需的。

所以基本上我需要的是“Person”实体列表,以及“SavedSearch”实体列表,其中“SendEmail”为真。

我也应该补充。我只想要包含匹配的“SavedSearch”子实体的“Person”实体。

【问题讨论】:

  • 你真的应该对集合使用复数名称,而只对返回单个实体的属性使用单数名称。 db.Person 应该是 db.Peopledb.Personsp.SavedSearch 应该是 p.SavedSearches。类型、成员和变量名称应尽可能自记录,因此应始终使用复数名称来表示数组或集合。
  • 谢谢@jmcilhinney 在这种情况下,我只是让 VS 使用默认设置从现有数据库创建模型,这就是它想出的。不过,我会在以后的项目中记住这一点。
  • 复数集合名称是使用数据库优先时的选项之一。在这种情况下,您应该检查所有可用的选项。您仍然可以重新运行向导并让它进行更改,您还可以在设计器中更改实体或属性名称。

标签: vb.net entity-framework linq-to-entities


【解决方案1】:

您使用Include 方法在查询结果中包含子实体:

Dim peopleWithDavedSearches = From p In db.Person.Include("SavedSearch")
                              Where p.SavedSearch.Any(Function(s) s.SendEmails)
                              Select p

如果有要填充的实体,peopleWithDavedSearches 中的每个 Person 对象都将填充其 SavedSearch 属性。

您也可以这样做:

Dim peopleWithDavedSearches = From p In db.Person.Include(Function(person) person.SavedSearch)
                              Where p.SavedSearch.Any(Function(s) s.SendEmails)
                              Select p

我不能 100% 确定现在标准 LINQ to Entities 是否提供该功能,或者您仍然需要额外的参考,但您可以尝试看看。

请注意,如果您想包含孩子的孩子,那么您只需使用点符号,例如

From item In list.Include("Child.GrandChild.GreatGrandChild")

如果您想在多个分支中包含后代,那么您只需多次调用Include,例如

From item In list.Include("Child1").Include("Child2")

【讨论】:

  • 实际上我意识到这并不是我所需要的。这是正确过滤“人”。然而,子集合“SaveSearch”仍然包括所有项目,无论“SendEmails”是否为真。我还想根据“SendEmails”的真实情况过滤子集合。这个可以吗。
  • 您不能通过查询Person 实体来做到这一点。您必须在事后过滤SavedSearch 集合,否则首先查询SavedSearch 实体并包括相关的Person。第二个选项会给你重复的Person实体。基本上,你不能只用一个查询来做你想做的事。
猜你喜欢
  • 2011-06-10
  • 1970-01-01
  • 2021-06-14
  • 1970-01-01
  • 1970-01-01
  • 2011-08-25
  • 1970-01-01
  • 2016-11-22
  • 1970-01-01
相关资源
最近更新 更多