linq - 如何使用 LINQ 连接子查询

标签 linq .net-core entity-framework-core

我是 Entity Framework 和 LINQ 的新手,正在努力将我的 SQL 查询“转换”为其语法。

Given 是一个包含生产订单的表,其中包含 OrderNumberQuantityMaterial 等列。另外还有一列时间戳

如果更新订单数量,则会在表中生成一个全新的条目,其中除时间戳(表示订单的时间)外,所有值都将与前一行相同。更改)和数量(包含新值)。从而使我能够拥有订单的“历史记录”。

使用 SQL 仅选择特定订单的最新版本可能如下所示:

SELECT p1.*
FROM dbo.ProductionOrders as p1
  JOIN (SELECT OrderNumber, MAX(Timestamp) as Timestamp FROM dbo.ProductionOrders GROUP BY OrderNumber) as p2
    on p1.OrderNumber = p2.OrderNumber and p1.Timestamp = p2.Timestamp
WHERE p1.OrderNumber = 'order-182736'

我在 C# 代码中完成了相同的功能,如下所示:

var productionOrder = _db.ProductionOrders.Where(po => po.OrderNumber == "order-182736")
                                          .OrderByDescending(po => po.Timestamp)
                                          .FirstOrDefault();

当我想要获取多行时,我会迷失方向。例如,特定 Material 的所有订单。使用 SQL,我只需调整 WHERE 条件:

SELECT p1.*
FROM dbo.ProductionOrders as p1
  JOIN (SELECT OrderNumber, MAX(Timestamp) as Timestamp FROM dbo.ProductionOrders GROUP BY OrderNumber) as p2
    on p1.OrderNumber = p2.OrderNumber and p1.Timestamp = p2.Timestamp
WHERE p1.Material = 42

我找到的使用 LINQ 的 JOIN 示例不对子查询进行操作(我的主要来源是 microsoft.com )

如何使用 LINQ 获取特定 Material 订单的所有最新“版本”?

最佳答案

您可以按照与 SQL 中完全相同的方式进行操作。 LINQ to Entities 中的 _db.ProductionOrders 表示 SQL 中的 dbo.ProductionOrders,您可以在顶级查询和子查询级别使用它:

var query = _db.ProductionOrders
    .Join(_db.ProductionOrders
        .GroupBy(p2 => new { p2.OrderNumber })
        .Select(g => new { g.Key.OrderNumber, Timestamp = g.Max(e => e.Timestamp) }), // subquery
        p1 => new { p1.OrderNumber, p1.Timestamp }, p2 => p2, // join condition
        (p1, p2) => p1) // result selector (p1.*)
    .Where(p1 => p1.Material == 42);

(注意:不确定 Label 在 SQL 查询中来自何处,因此使用 OrderNumber 代替)。

或者,如果您愿意,也可以使用相同的 LINQ 查询语法:

var query =
    from p1 in _db.ProductionOrders
    join p2 in (from p2 in _db.ProductionOrders
                group p2 by new { p2.OrderNumber }) into g
                select new { g.Key.OrderNumber, Timestamp = g.Max(p2 => p2.Timestamp) })
    on new { p1.OrderNumber, p1.Timestamp } equals p2
    where p1.Material == 42
    select p1;

关于linq - 如何使用 LINQ 连接子查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63342251/

相关文章:

docker - 带有 .net core 3.1 Web 应用程序的 docker 容器问题

c# - 如何正确使用 ExecutionStrategy?

c# - 注入(inject) DbContext 时无法访问 ASP.NET Core 中已处置的对象

c# - 通过另一个条件更改 LINQ 中的条件

c# - 如何使这两种方法更有效

c# - NuGet 元数据包是否仅保留给 .net 核心?

entity-framework-core - EntityFrameworkCore : How to initialize a Database and seed it the first time user uses an application

C#:在 foreach 中使用 Take() is 语句可以使用吗?

c# - 如何在 C# 中使用 LINQ 方法或查询表达式检索最后 5 条记录

asp.net-core - .NET Core 与 ASP.NET Core