[英]How to JOIN a Sub-Query using LINQ
I am new to Entity Framework and LINQ and am struggling to "convert" my SQL query to its syntax.我是 Entity Framework 和 LINQ 的新手,并且正在努力将我的 SQL 查询“转换”为其语法。
Given is a table that contains production orders with OrderNumber
, Quantity
, Material
etc. as columns.给定的表格包含以
OrderNumber
、 Quantity
、 Material
等为列的生产订单。 Additionally there is a column Timestamp
.此外还有一列
Timestamp
。
If the quantity of an order would be updated, this results in a completely new entry in the table where all values would be the same as a previous row except for Timestamp
(indicating the time of the change) and Quantity
(containing the new value).如果要更新订单的数量,则会在表中产生一个全新的条目,其中所有值都与前一行相同,除了
Timestamp
(指示更改时间)和Quantity
(包含新值) . Thus allowing me to have a "history" of an order.从而让我有一个订单的“历史”。
Selecting only the latest version of a specific order using SQL could look like this:使用 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'
The same functionality I got done in my C# code like this:我在 C# 代码中完成的功能相同,如下所示:
var productionOrder = _db.ProductionOrders.Where(po => po.OrderNumber == "order-182736")
.OrderByDescending(po => po.Timestamp)
.FirstOrDefault();
Where I am lost is when I want to get multiple rows.当我想获得多行时,我迷路了。 For example all orders for a specific material.
例如,特定材料的所有订单。 Using SQL I only have to adjust the
WHERE
condition:使用 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
The examples I found for JOIN
using LINQ don't operate on sub-queries (my main source is microsoft.com )我使用 LINQ 为
JOIN
找到的示例不适用于子查询(我的主要来源是microsoft.com )
How can I get all latest "versions" of orders for a specific material using LINQ?如何使用 LINQ 获得特定材料的所有最新“版本”订单?
You can do it the exact same way as in SQL.您可以按照与 SQL 完全相同的方式进行操作。
_db.ProductionOrders
in LINQ to Entities represents the dbo.ProductionOrders
in SQL, and you can use it in both top and subquery level: _db.ProductionOrders
中的 _db.ProductionOrders 到 Entities 表示dbo.ProductionOrders
中的 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);
(Note: Not sure where Label
is coming from in your SQL queries, so using OrderNumber
instead). (注意:不确定
Label
在您的 SQL 查询中来自何处,因此请改用OrderNumber
)。
or if you prefer, the same in LINQ query syntax:或者,如果您愿意,也可以使用 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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.