【问题标题】:How to add left outer join to grouped and summed LINQ query如何将左外连接添加到分组和求和的 LINQ 查询
【发布时间】:2012-11-25 21:47:00
【问题描述】:

我有一个雇员表:

EmployeeID  |  EmployeeName
---------------------------
1           |  Jack
2           |  Jill
3           |  Roger

还有一个 Occurrences 表:

OccurrenceID  |  EmployeeID  |  Points
--------------------------------------
1             |  1           |  5
2             |  2           |  3
3             |  1           |  1

我有一个有效的 LINQ 查询,它将两个表分组和汇总在一起:

groupedOccurrences = (from o in db.Occurrences.Include(o => o.Employee)
                      where o.OccurrenceDate >= beginDate
                         && o.OccurrenceDate <= endDate
                      group o by o.Employee.EmployeeName into g
                      select new OccurrenceByQuarter
                      {
                          Name = g.Key,
                          Total = g.Sum(o => o.Points)
                       });

产生这个输出:

 Jack 6
 Jill 3

但我还想让员工 Roger 以 0 分出现在输出中。我试过像这样向 LINQ 查询添加连接:

groupedOccurrences = (from e in db.Employees
                      from o in db.Occurrences
                      join o in db.Occurrences on e.EmployeeID equals o.EmployeeID into j1
                      from j2 in j1.DefaultIfEmpty()
                      group j2 by e.EmployeeName into g
                      select new OccurrenceByQuarter
                      {
                          Name = g.Key,
                          Total = g.Sum(o => o.Points)
                      });

但我最终得到的分数被大大夸大了(就像他们应该的 24 倍一样)。

我还尝试通过在我的 OccurrencesByQuarter 类中将 Total 的声明更改为 public int? Total { get; set; } 来使 Total 返回 0,但是当我尝试将 LINQ 查询更改为包含 Total = g.Sum(o =&gt; o.Points) ?? 0 时,我收到一个错误上面写着“运算符 ?? 不能应用于 int 和 int 类型的操作数”。

任何帮助将不胜感激。

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    使用群组加入:

    groupedOccurrences = (from e in db.Employees
                          join o in db.Occurrences.Where(x => 
                                      x.OccurrenceDate >= beginDate &&
                                      x.OccurrenceDate <= endDate)
                               on e.EmployeeID equals o.EmployeeID into g
                          select new OccurrenceByQuarter
                          {
                              Name = e.EmployeeName,
                              Total = g.Sum(x => (int?)x.Points) ?? 0
                          });
    

    结果将是:

    Jack  6
    Jill  3
    Roger 0
    

    为了返回空组的0,将汇总属性转换为可空,然后应用空合并运算符返回默认值:g.Sum(x =&gt; (int?)x.Points) ?? 0

    【讨论】:

    • 太棒了! “into g”使 linq 语句有效地成为外连接,如果省略了 into 子句,它只会执行普通连接,并且只会检索匹配的行。并且会有员工 x 出现他们与这里产生的好群体
    猜你喜欢
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多