返回基于(并包括)子实体的父实体



我试图检索基于其子实体的属性的实体列表-并包括那些相同的子实体。我正在使用EntityFramework Core 3.1,虽然我很高兴升级到5。X,如果有任何改变可以帮我解决这个问题。到目前为止,除了一些非常基本的CRUD样板,我还没有探索过EntityFramework,所以我不确定这是更面向linq的还是特定于EF (Core)的东西。下面是一个非常简化的项目方法示例,我将使用它最终将数据返回给我的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();
然而,我的问题是……然后,我如何根据该POIHistory中的属性仅获得POIs(并包括相同的History记录?)或者,举个例子;我想只返回具有areaId == 5History记录的POIs(并将其包括在结果中)

如果没有非常深入的EF知识,一种方法是:

  • 首先运行查询返回History实体,其中history.areaId == 5只选择history.PointId
  • 第二个查询将获得所有POI,其中id在上面返回的PointId列表中
  • . .history.areaId == 5(副本)
  • 包括History

然而,我将其中的一部分运行两次,这似乎效率低下。基本上,我可以有效地使用LINQ/EF来获得所有POIs,其中history.areaId == 5(然后仅包括areaId为5的History记录)?在我能够缩小结果之前,我是否必须写一些不可避免地加载所有POI及其History记录的东西,或者是EF可以愉快地做的事情?

您可以使用EF Core 5中引入的Filtered include。X,查询类似-

var result = _context.POIs
.Include(p => p.Histories.Where(h => h.areaId == 5))            
.ToList();

这将返回POI的列表,其中每个列表将只包含areaId == 5.

编辑:
如果您只想要具有HistoryareaId == 5POIs,您可以简单地相应地过滤它们-

var result = dbCtx.POIs
.Include(p => p.Histories.Where(h => h.areaId == 5))
.Where(p => p.Histories.Any(h => h.areaId == 5))
.ToList();

您应该能够使用以下命令:

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

最新更新