根据双重嵌套实体的属性对主要实体进行排序

Sorting Primary Entities on Properties of Doubly-Nested Entities

我正在使用 Entity Framework Core 和 ASP.Net MVC。我的业务对象模型部分由工作(主要实体)组成,每个工作包含一个或多个项目,每个项目有零个或多个计划(link 到一组部门,但这并不重要这里)。每个计划都有一个 StartDate 和 EndDate。

这是一个(简化的)class 图表(它反映了您所期望的数据库模式):

我想按 Schedule 实体中最早的 StartDateTime 值对 Jobs 列表进行排序。我还没有想出一个 LINQ 链来完成这个。目前,我已经通过在我的控制器中直接使用 ADO.Net 来获得我想要的功能,以 assemble 基于以下 SQL 语句的作业列表:

@"SELECT
    Jobs.JobId, 
    Jobs.JobName, 
    Jobs.jobNumber,
    MIN(ProjectSchedules.StartDateTime) AS StartDateTime
FROM 
    Jobs INNER JOIN Projects ON Jobs.JobID = Projects.JobID
         LEFT JOIN ProjectSchedules ON Projects.ProjectID = ProjectSchedules.ProjectID
GROUP BY Jobs.JobId, Jobs.JobName, Jobs.JobNumber 
ORDER BY StartDateTime"

我更愿意正确使用 EF Core,而不是围绕它做一个 end-运行。生成此 SQL 语句(或等效语句)的 LINQ 语句是什么?

首先我们需要检索我们可以使用 Include 语句执行此操作的所有实体,然后我们使用 theninclude 进一步检索实体。

dbcontext.Jobs.Include(j => j.Projects).ThenInclude(p => p.Schedules)

现在我们拥有了所有实体,您可以进行所有排序、分组或任何您想做的事情。

对我来说,你想在 schedule.startdatetimeOrderby

您需要一个查询来“收集”每个作业的项目进度表中的所有 StartDateTime,取其最低值然后按该值排序:

context.Jobs
    .OrderBy(j => j.Projects
        .SelectMany(p => p.Schedules)
        .Select(s => s.StartDate).OrderBy(d => d).First())
    .Select(j => new { ... })

如您所见,其中甚至没有 Min 函数。可以使用该函数,但它的性能可能更差,因为它必须评估所有 StartDate 值,而排序 可以 使用有序索引。

无论哪种方式,为了比较,这是 Min():

context.Jobs
    .OrderBy(j => j.Projects
        .SelectMany(p => p.Schedules)
        .Select(s => s.StartDate).Min())