基于(包括)子实体返回父实体
Posted
技术标签:
【中文标题】基于(包括)子实体返回父实体【英文标题】:Return parent entities based on (and including) child entities 【发布时间】:2021-06-06 13:54:45 【问题描述】:我正在尝试根据子实体的属性检索实体列表 - 并包括那些相同的子实体。我正在使用 EntityFramework Core 3.1,但如果有任何更改可以为我解决这个问题,我很乐意升级到 5.x。到目前为止,除了一些非常基本的 CRUD 样板之外,我还没有探索过 EntityFramework,所以我不确定这是否更面向 LINQ 或特定于 EF(核心)。下面是项目中方法的一个高度简化的示例,我将使用该方法最终将数据返回给我的 API 的使用者。
兴趣点 (POI
) 有许多历史记录 (History
)。 POI 有一个 List<History>
,History 有一个 PointID
,EF Core 使用它来填充 POI 的 List<History>
。
以下是我如何获取所有 POI 及其历史记录,其中一个点自某个日期以来首次注册(此方法使用可为空的日期参数)
var result = _context.POIs
.Where(point => (registeredSince == null || point.RegisteredAt >= registeredSince))
.Include(point => point.Histories)
.ToList();
但是,我的问题是.. 然后我将如何根据POI
的History
中的属性仅获得POI
s(并包括那些相同的History
记录?)或者,使用例子;我只想返回具有History
记录和areaId == 5
的POI
s(并将这些记录包含在结果中)
如果没有非常深入的 EF 知识,一种方法是:
首先运行查询以返回History
实体,其中history.areaId == 5
并仅选择history.PointId
第二个查询是获取所有POI
s,其中id
在上面返回的PointId
列表中
..包括History
where history.areaId == 5
(重复)
但是,我会运行其中的一部分两次,这似乎效率低下。基本上,我是否可以有效地使用 LINQ/EF 来获取所有 POI
s 其中 history.areaId == 5
(然后只包括那些 History
记录,areaId
为 5)?在我能够缩小结果范围之前,我是否必须编写一些不可避免地加载所有 POI
及其 History
记录的内容,或者 EF 可以愉快地做些什么?
【问题讨论】:
【参考方案1】:您可以使用 EF Core 5.x 中引入的Filtered include 进行查询 -
var result = _context.POIs
.Include(p => p.Histories.Where(h => h.areaId == 5))
.ToList();
这将返回POI
的列表,其中每个列表仅包含areaId == 5
的历史记录。
编辑:
如果你只想要POI
s 中的History
和areaId == 5
,你可以简单地过滤它们-
var result = dbCtx.POIs
.Include(p => p.Histories.Where(h => h.areaId == 5))
.Where(p => p.Histories.Any(h => h.areaId == 5))
.ToList();
【讨论】:
这几乎可以工作,除非我不希望返回没有历史记录的 POI(即我只想返回.Histories.Where(h => h.areaId == 5)
的 POI)。之后我可以删除所有没有历史记录的 POI,但理想情况下我不希望它们重新开始......
这正是答案 - 昨天让我难过的是.Any
!【参考方案2】:
您应该能够使用以下内容:
var result = _context.POIs
.Include(poi => poi.Histories)
// Enumerate linked Histories & get the areaId from each into a list)
// ... then see if that list contains the areaID we're looking for.
.Where(poi => poi.Histories.Select(h => h.areaId).Contains(areaIdParam))
.ToList();
【讨论】:
以上是关于基于(包括)子实体返回父实体的主要内容,如果未能解决你的问题,请参考以下文章
Restkit/Core Data 关系映射,实体到相同类型的实体(父/子)