使用OrderBy和GroupBy从SQL创建Linq
本文关键字:SQL 创建 Linq GroupBy OrderBy 使用 | 更新日期: 2023-09-27 18:28:05
我有以下表格结构。
TableA TableB TableC
- MID - PID - PID
- NAME - INIT_DATE - MID
这是我需要翻译成Linq的SQL查询
SELECT TOP 10 TableA.NAME,
COUNT(TableB.INIT_DATE) AS [TOTALCOUNT]
FROM TableC
INNER JOIN TableA ON TableC.MID = TableA.MID
LEFT OUTER JOIN TableB ON TableC.PID = TableB.PID
GROUP BY TableA.NAME
ORDER BY [TOTALCOUNT] DESC
我试图用这个Linq查询重现上面的查询:
iqModel = (from tableC in DB.TableC
join tableA in DB.TableA on tableC.MID equals tableA.MID
select new { tableC, tableA } into TM
join tableB in DB.TableB on TM.tableC.PID equals J.PID into TJ
from D in TJ.DefaultIfEmpty()
select new { TM, D } into MD
group MD by MD.TM.tableA.NAME into results
let TOTALCOUNT = results.Select(item=>item.D.INIT_DATE).Count()
orderby TOTALCOUNT descending
select new SelectListItem
{
Text = results.Key.ToString(),
Value = TOTALCOUNT.ToString()
}).Take(10);
但我觉得我做错了什么。
LINQ和SQL的输出不相同。我认为无论是JOIN还是GROUPBY都是正确的。
编辑:-
我也尝试过以下Linq查询,但仍然无法正常工作
var iqModel = (from c in DB.TableC
join a in DB.TableA on c.MID equals a.MID
join b in DB.b on c.PID equals b.PID into b_join
from b in b_join.DefaultIfEmpty()
select new SelectListItem { Text = a.NAME, Value = b.INIT_DATE != null ? b.INIT_DATE.ToString() : string.Empty });
var igModel = iqModel.GroupBy(item => item.Text);
var result = igModel.OrderByDescending(item => item.Select(r => r.Value).Count());
我想了解我做错了什么,以及如何解决。
我是LINQ to SQL的新手,我认为在上面的LINQ中,我添加了更多的选择,这真的让它变得复杂了。
我认为这种差异是由于SQL COUNT(field)
函数不包括NULL
值这一事实造成的。LINQ中没有直接的等价结构,但它可以用Count(e => e.Field != null)
或类似的结构来模拟(这似乎可以产生更好的SQL):
var query =
(from a in db.TableA
join c in db.TableC on a.MID equals c.MID
join b in db.TableB on c.PID equals b.PID into joinB
from b in joinB.DefaultIfEmpty()
group b by a.Name into g
let TOTALCOUNT = g.Sum(e => e.INIT_DATE != null ? 1 : 0)
orderby TOTALCOUNT descending
select new SelectListItem { Text = g.Key, Value = TOTALCOUNT }
).Take(10);
它生成以下SQL
SELECT TOP (10)
[Project1].[C2] AS [C1],
[Project1].[Name] AS [Name],
[Project1].[C1] AS [C2]
FROM ( SELECT
[GroupBy1].[A1] AS [C1],
[GroupBy1].[K1] AS [Name],
1 AS [C2]
FROM ( SELECT
[Join2].[K1] AS [K1],
SUM([Join2].[A1]) AS [A1]
FROM ( SELECT
[Extent1].[Name] AS [K1],
CASE WHEN ([Extent3].[INIT_DATE] IS NOT NULL) THEN 1 ELSE 0 END AS [A1]
FROM [dbo].[TableAs] AS [Extent1]
INNER JOIN [dbo].[TableCs] AS [Extent2] ON [Extent1].[MID] = [Extent2].[MID]
LEFT OUTER JOIN [dbo].[TableBs] AS [Extent3] ON [Extent2].[PID] = [Extent3].[PID]
) AS [Join2]
GROUP BY [K1]
) AS [GroupBy1]
) AS [Project1]
ORDER BY [Project1].[C1] DESC
我假设,您在结果查询中看不到"groupby"命令,而是使用了"distinct"命令。我说得对吗?
第一个查询通过TableA.NAME进行区分,然后在下面的子查询的帮助下计算COUNT(TableB.INIT_DATE):
select distinct1.Name, (select count() from *join query* where Name = distinct1.Name)
from (select distinct Name from *join query*) as distinct1
如果是这样,那就不用担心了。因为从linq到真正的t-sql脚本的转换有时非常不可预测(你不能强迫它们相等,只有当查询非常简单时),但两个查询都是等价的,并且返回相同的结果(比较它们以确保)。