【问题标题】:LINQ returning duplicate rows while SQL isn'tLINQ 返回重复的行,而 SQL 不是
【发布时间】:2017-06-01 20:16:30
【问题描述】:

我正在编写一个 C# LINQ 代码,我试图通过按 Table1 中的列分组来连接两个表

下面是返回正确结果的 SQL 查询

SELECT
    SUM(scr.Count),spl.Name
FROM    Table1 scr
        ,Table2 spl
WHERE scr.StatusId = spl.StatusId
 GROUP by spl.Name

返回错误结果的等效 LINQ

(from l in _dataContext.Table1
                     join r in
                     _dataContext.Table2 on
                     new {  l.StatusId } equals new { r.StatusId }
                     into gj
                     from r in gj.DefaultIfEmpty()                   
                     select new
                     {
                         l.Name,
                         Count = gj.Sum(j => j.Count)
                     }).GroupBy(l => l.Name).Select(x => new DataPoint
                     {
                         Name = x.Key,
                         Y = x.Sum(y => y.Count)
                     }).ToList();

无法找出错误,有没有更好的方法来获得与上述 SQL 查询等效的结果?

【问题讨论】:

  • 是的,你需要学习 LINQ。它不像 SQL。
  • 您的 Linq 代码正在执行左连接,这就是 DefaultIfEmpty 所做的。
  • 应该在你的 SQL 代码中使用明确的JOIN
  • 查看 msdn 了解左外连接:code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

标签: c# sql-server linq join


【解决方案1】:

逐字对应

var results = (from l in db.Table1
               from r in db.Table2
               where l.StatusId == r.StatusId
               group j.Count by l.Name into g
               select new {
                   Name = g.Key,
                   Count = g.Sum()
               }).ToList();

更正确的联接版本不会将intojoin(也称为组联接)或DefaultIfEmpty 一起使用,因为这会导致左联接。相反,您只需使用常规 group by 作为查询语法的一部分,而不是使用 Method 语法不必要地附加它。

var results = (from l in db.Table1
               join j in db.Table2 on l.StatusId equals r.StatusId
               group j.Count by l.Name into g
               select new {
                   Name = g.Key,
                   Count = g.Sum()
               }).ToList();

如果你真的想要所有的名字,那么这就是你要做左连接的方式。

var results = (from l in db.Table1
               join j in db.Table2 on l.StatusId equals r.StatusId into lrs
               from lr in lrs.DefaultIfEmpty()
               group lr.Count by l.Name into g
               select new {
                   Name = g.Key,
                   Count = g.Sum()
               }).ToList();

或者,如果 Count 列不可为空,您可能必须强制转换它才能使其工作

group (int?)lr.Count by l.Name into g

【讨论】:

  • 你更正确的加入版本仍然使用into :)
  • @NetMage 是的,作为 group by 的一部分,而不是 join 的一部分,但我会在答案中澄清这一点。
  • @juharr 我想在 table1 中包含所有名称,即使 table2 中没有匹配项
  • @DoIt 这不是你的 SQL 正在做的事情。
  • @juharr 我是这么认为的,但现在我想包含它们,如果我使用 defaultifEmpty 它会再次导致冗余
猜你喜欢
  • 1970-01-01
  • 2012-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-25
  • 2012-09-02
  • 2018-06-25
  • 1970-01-01
相关资源
最近更新 更多