在 C# 中使用组和连接进行 LINQ 查询

Posted

技术标签:

【中文标题】在 C# 中使用组和连接进行 LINQ 查询【英文标题】:LINQ query in C# using group and join 【发布时间】:2015-11-23 08:15:26 【问题描述】:

我正在尝试在 LINQ C# 中编写以下 SQL 查询,但无法获取 group 子句之后的列。

SQL 查询

/*get the number of questions by subject*/

select b.SubjectID, b.SubjectName, count(*) AS count 
from QuestionsTable a, SubjectTable b
where a.SubjectID is not null AND a.SubjectID = b.SubjectID
GROUP BY a.SubjectID

LINQ 查询

var result =(from a in db1.QuestionsTables
             join b in db1.SubjectTables 
             on a.SubjectID equals b.SubjectID
             where a.SubjectID != null
             group a by a.SubjectID  into g
             select new  a.QuestionID, a.SubjectID, b.SubjectName
             ).ToList();            

【问题讨论】:

您确定您的 SQL 查询正确吗?我不认为这是因为 SubjectName 既不存在于 group by 子句中,也不存在于任何聚合函数中。 是的,SQL 查询是正确的。它正在返回预期结果 你在用SQL Server吗? 【参考方案1】:

您的 SQL 将无法正确执行,因为您通过 a.Subject.ID 查询组,但选择了 b.SubjectIDb.SubjectName。通常您还应该将单个选定字段包含到GROUP BY 列表中。

(据我所知,一些 SQL 服务器可以处理功能依赖字段,因此它们可以处理您的查询。但总的来说这是错误的)。

所以你的工作查询应该是:

SELECT b.SubjectID, b.SubjectName, COUNT(*) AS Count 
FROM QuestionsTable a, SubjectTable b
WHERE a.SubjectID is not null AND a.SubjectID = b.SubjectID
GROUP BY b.SubjectID, b.SubjectName

你的 LINQ 应该是

from a in db.QuestionsTable
join b in db.SubjectTable
  on a.SubjectId equals b.SubjectId
where a.SubjectId != null
group b by new  b.SubjectId, b.SubjectName  into g
select new  g.Key.SubjectId, g.Key.SubjectName, g.Count() 

【讨论】:

@RahulSingh 已更新。谢谢。 感谢您提供有关函数依赖字段的提示,Mark。【参考方案2】:

虽然可以按照你要求的方式制作,但可以通过更简单自然的方式获得相同的结果,根本不涉及分组,就像这样

// get the number of questions by subject
var result =
    (from s in db1.SubjectTables
     select new
      
         s.SubjectID,
         s.SubjectName,
         Count = db1.QuestionsTables.Count(q => q.SubjectID == s.SubjectID)
     ).ToList();

更新:不管投反对票如何,我坚信这是解决这个特殊问题的正确方法——简单而自然。为什么要对已经分组的东西进行分组(按主键)。

【讨论】:

这几乎肯定会为表中的每一行执行查询,导致性能极差。 @Corey 这在很久以前可能是正确的 - 现在数据库查询优化器非常有效地处理子查询,实际上可以在需要时将它们变成连接。在这种特殊情况下,很可能会使用简单的索引范围搜索。

以上是关于在 C# 中使用组和连接进行 LINQ 查询的主要内容,如果未能解决你的问题,请参考以下文章

使用 LINQ 或其他模块在 C# 中连接两个查询的结果

如何在 C# 中使用 LINQ 应用右外连接?

使用 LINQ 查询语法 EF Core C# 的左外连接

如何使用基于 SQL Query 的连接在 C# 中编写 LINQ?

如何在 LINQ 中使用左外连接进行 SQL 查询?

LinQ 创建连接简单增删改查