当SQL不是时,LINQ返回重复的行

时间:2017-06-01 20:16:30

标签: c# sql-server linq join

我正在编写一个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查询?

1 个答案:

答案 0 :(得分:3)

逐字等同于

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一起使用,因为这会导致左联接。相反,您只需使用常规组作为查询语法的一部分,而不是使用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