【问题标题】:EF Core 3.1 (LINQ) - how to left join and group by on multiple columnsEF Core 3.1 (LINQ) - 如何在多列上左加入和分组
【发布时间】: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

标签: c# sql-server linq lambda ef-core-3.1


【解决方案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 可以在点击时做到这一点。
猜你喜欢
  • 2021-08-22
  • 1970-01-01
  • 1970-01-01
  • 2021-05-06
  • 2021-07-28
  • 2020-09-10
  • 2021-08-20
  • 2020-05-15
  • 1970-01-01
相关资源
最近更新 更多