我如何在LINQ中执行此SQL

时间:2018-04-08 01:26:11

标签: c# sql linq

我有一些我可以在SQL中轻松完成的事情,但我无法弄清楚如何在LINQ中做到这一点。所以我有3个表:ReturnReturnItemReturnItemTestReturn有1..n ReturnItem s,ReturnItem有0..1 ReturnItemTests。表格如下所示:

Return
======
ReturnId int not null (PK)
ReturnName nvarchar(max) not null

ReturnItem
==========
ReturnItemId int not null (PK)
ReturnId int not null (FK)
ReturnItemStatus int not null

ReturnItemTest
==============
ReturnItemId int not null (PK, FK)
ReturnItemTestStatus int not null

每个返回都有返回项,每个返回项可能有0或1个测试。返回项目和退货项目测试都具有状态。我想计算有多少退货项目状态代码和退货项目测试状态代码,按两者的状态编号分组。但是,需要LEFT OUTER JOIN,因为退货项目可能没有测试。所以在SQL中我说:

SELECT
          ri.[ReturnItemStatus] AS ItemStatus,
          rit.[ReturnItemTestStatus] AS TestStatus,
          COUNT([ReturnItem].[ReturnItemStatus]) as ComboCount
FROM
          [Return] r
          INNER JOIN [ReturnItem] ri ON r.ReturnId = ri.ReturnId
          LEFT OUTER JOIN [ReturnItemTest] rit ON ri.ReturnItemId = rit.ReturnItemId
GROUP BY
          ri.[ReturnItemStatus], rit.[ReturnItemTestStatus]

这给我一个结果,显示退货项目状态,退货项目测试状态和每个组合的计数的所有现存组合。如何使用LINQ实现相同的目标?我到目前为止:

var returns =
    (
        from r in ctx.Returns
        join ri in ctx.ReturnItems on r.ReturnID equals ri.ReturnID
        join rit in ctx.ReturnItemTests on ri.ReturnItemID equals rit.ReturnItemTestID into ritJoined
        from rit in ritJoined.DefaultIfEmpty()
        select new {
            ReturnItemStatus = ri.ReturnItemStatus,
            ReturnItemTestStatus = rit == null ? null : (int?)rit.ReturnItemTestStatus
        }
    ).ToList();

...它向我显示了测试状态的返回项状态LEFT OUTER JOIN,但我无法弄清楚如何使分组和计数工作。

2 个答案:

答案 0 :(得分:1)

由于你根本不使用Return表,我会跳过它。你有这个查询

SELECT
          ri.[ReturnItemStatus] AS ItemStatus,
          rit.[ReturnItemTestStatus] AS TestStatus,
          COUNT(*) as ComboCount
FROM
          [ReturnItem] ri
          LEFT OUTER JOIN [ReturnItemTest] rit ON ri.ReturnItemId = rit.ReturnItemId
GROUP BY
          ri.[ReturnItemStatus], rit.[ReturnItemTestStatus]

虽然您可以只对查询添加分组,但这可能不是最好的方法。即使不需要,也明确定义连接键。在您的情况下,每个项目最多只能有一个测试,因此您应该能够写下这个:

ctx.ReturnItems
   .Select(ri => new { ri.ReturnItemStatus, ri.ReturnItemTest.ReturnItemTestStatus })
   .GroupBy(x => x, (x, y) => new { x.ReturnItemStatus, x.ReturnItemTestStatus, Count = y.Count() })

注意,ri.ReturnItemTest.ReturnItemTestStatus在sql server上执行,当ReturnItemTest为空时,它将返回null作为服务器的默认行为。

答案 1 :(得分:0)

这就是我最终设法做到的:

{{1}}