Entity framework 基于(包括)子实体返回父实体

Entity framework 基于(包括)子实体返回父实体,entity-framework,linq,.net-core,entity-framework-core,Entity Framework,Linq,.net Core,Entity Framework Core,我正在尝试根据子实体的属性检索实体列表,并包括这些相同的子实体。我正在使用EntityFrameworkCore3.1,不过如果有任何改变可以解决这个问题,我很乐意升级到5.x。到目前为止,除了一些非常基本的CRUD样板文件之外,我还没有深入研究EntityFramework,所以我不确定这是更面向LINQ的还是特定于EF(核心)的。下面是一个非常简化的项目中的方法示例,我将使用该方法最终将数据返回给API的使用者 兴趣点(POI)有许多历史记录(History)。POI有一个列表,历史记录有一

我正在尝试根据子实体的属性检索实体列表,并包括这些相同的子实体。我正在使用EntityFrameworkCore3.1,不过如果有任何改变可以解决这个问题,我很乐意升级到5.x。到目前为止,除了一些非常基本的CRUD样板文件之外,我还没有深入研究EntityFramework,所以我不确定这是更面向LINQ的还是特定于EF(核心)的。下面是一个非常简化的项目中的方法示例,我将使用该方法最终将数据返回给API的使用者

兴趣点(
POI
)有许多历史记录(
History
)。POI有一个
列表
,历史记录有一个
点ID
,EF Core使用该ID填充POI的
列表

下面是我如何获取所有POI及其历史记录的方法,其中一个点是从某个日期开始首次注册的(使用此方法的可空日期参数)

var result=\u context.POIs
.Where(point=>(registeredSince==null | | point.RegisteredAt>=registeredSince))
.Include(点=>点历史记录)
.ToList();
然而,我的问题是。。然后,我如何根据
POI
历史
中的属性(并包括相同的
历史
记录)仅获取
POI
呢;我只想返回
POI
s,这些POI具有
History
记录且
areaId==5
(并将这些记录包括在结果中)

一种方法是,在没有深入了解环境足迹的情况下:

  • 首先运行查询以返回
    History
    实体,其中
    History.areaId==5
    ,并仅选择
    History.PointId
  • 第二个查询是获取所有
    POI
    s,其中
    id
    位于上面返回的
    PointId
    列表中
  • …包括
    历史
    其中
    历史.areaId==5
    (重复)

然而,我会两次运行其中的一部分,这似乎效率低下。基本上,我可以有效地使用LINQ/EF来获取所有
POI
s,其中
history.areaId==5
(然后只包括那些
history
记录,其中
areaId
为5)?在我能够缩小结果范围之前,我是否必须编写一些不可避免地加载所有
POI
及其
历史记录的内容,或者EF可以很高兴地这样做?

您应该能够使用以下内容:

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();
您可以使用EF Core 5.x中引入的-

var result=\u context.POIs
.Include(p=>p.Histories.Where(h=>h.areaId==5))
.ToList();
这将返回一个
POI
列表,其中每个POI仅包含
areaId==5的历史记录

编辑:
如果只需要具有
areaId==5的
POI
s的
History
,只需相应地对其进行过滤即可-

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

这几乎可以实现,但如果没有历史记录,我不希望返回POI(即我只想返回
.histories.Where(h=>h.areaId==5)
)。我可以在事后删除所有没有历史记录的POI,但理想情况下,我不想让它们从..@Trevelyan开始返回。请检查编辑。这正是答案-是
。昨天让我难堪的任何