EF Core 3.1 (LINQ) - 如何在多列上左加入和分组
Posted
技术标签:
【中文标题】EF Core 3.1 (LINQ) - 如何在多列上左加入和分组【英文标题】:EF Core 3.1 (LINQ) - how to left join and group by on multiple columns 【发布时间】:2021-06-12 22:25:39 【问题描述】:假设我有 3 个关系: classA(aID#, aName, aNumber), classB(bID#, bName, bNumber, aId), classC(cID#, cName, cNumber, bId)
并根据那 3 个带有一些随机数据的表:
A 类
aID | aName | aNumber |
---|---|---|
1 | aN1 | 5 |
2 | aN2 | 4 |
3 | aN3 | 3 |
B类
aID | aName | aNumber | bID |
---|---|---|---|
1 | bN1 | 3 | 1 |
2 | bN2 | 4 | 1 |
3 | bN3 | 5 | 2 |
类C
aID | aName | aNumber | bID |
---|---|---|---|
1 | cN1 | 6 | 1 |
2 | cN2 | 6 | 2 |
3 | cN3 | 7 | 3 |
现在,使用 T-SQL 语法如下:
select a.aID, a.aName, sum(c.cNumber) as SUM
from classA a
left join classB b on a.aID = b.aId
left join classC c on b.bID = c.bId
group by a.AID, a.aName, c.Number
所以我得到这样的结果:
aID | aName | SUM |
---|---|---|
1 | aN1 | 12 |
2 | aN2 | 7 |
3 | aN3 | 0 |
如何根据上面的解释创建正确的 lambda 表达式语法?
【问题讨论】:
当我执行该查询时(修正错字后),我在 SUM 列中得到 [6 6 7] (我在求和c.aNumber
时预期)。见sqlfiddle.com/#!9/850137/2
【参考方案1】:
试试这个查询:
var query =
from a in ctx.A
from b in ctx.B.Where(b => a.aID == b.aId).DefaultIfEmpty()
from c in ctx.C.Where(c => b.bID == c.bId).DefaultIfEmpty()
group c by new a.aID, a.aName, c.cNumber into g
select new
g.Key.aID,
g.Key.aName,
Sum = g.Sum(x => x.cNumber)
;
并使用 LINQ 方法链语法:
var query2 = ctx.A
.SelectMany(a => ctx.B.Where(b => a.aID == b.aId).DefaultIfEmpty(), (a, b) => new a, b)
.SelectMany(t => ctx.C.Where(c => t.b.bID == c.bId).DefaultIfEmpty(), (t, c) => new t, c)
.GroupBy(t => new t.t.a.aID, t.t.a.aName, t.c.cNumber, t => t.c)
.Select(g => new g.Key.aID, g.Key.aName, Sum = g.Sum(x => x.cNumber));
【讨论】:
谢谢。但是你能把这个语法转换成 LINQ 方法语法吗? 我可以,但会一团糟。当您有很多连接时,最好保留查询语法。无论如何,ReSharper 可以在点击时做到这一点。以上是关于EF Core 3.1 (LINQ) - 如何在多列上左加入和分组的主要内容,如果未能解决你的问题,请参考以下文章
如何在 EF Core 和 LINQ 中表达 GetDate() 和 DateAdd() 方法?
如何将带有 LEFT JOIN 的 SQL 转换为 EF CORE 3 LINQ