LINQ计数..最佳方法

3

我公司刚开始使用LINQ,但是我对LINQ命令和SQL的抽象性仍然有些困惑,我的问题是:

  Dim query = (From o In data.Addresses _
                    Select o.Name).Count

在我的理解中,SQL语句返回所有行,并对IQueryable结果中的行数进行计数,因此最好使用

    Dim lstring = Aggregate o In data.Addresses _
    Into Count()

我是否过度思考了LINQ的工作方式?在家中使用VB Express,无法查看发送到数据库的实际SQL(我认为),因为我没有访问SQL分析器的权限。

5
毫无附属关系(不是代言),我建议您看一下 LINQPad - http://www.linqpad.net/,它允许您查看从 LINQ to SQL 表达式生成的 SQL,对于 VB 和 C# 都适用,使得在不重建/重新运行查询片段时有些更容易处理。 - Marc Bollinger
@Marc 谢谢,这让我自己回答了问题....很好的工具....顺便说一句,请把它作为答案,这样我就可以打勾了 :-) - spacemonkeys
4个回答

7

如前所述,这些在功能上是等价的,只是一个使用了查询语法。

如我在评论中提到的,如果您在LINQPad中将以下内容作为VB语句进行评估:

Dim lstring = Aggregate o In Test _
    Into Count()

您将在生成的SQL输出窗口中看到以下内容:
SELECT COUNT(*) AS [value]
FROM [Test] AS [t0]

这与以下VB LINQ表达式的评估结果相同:

(From o In Test_
    Select o.Symbol).Count

您将获得完全相同的结果。

2
我不熟悉Visual Basic,但根据http://msdn.microsoft.com/en-us/library/bb546138.aspx,这两种方法是相同的。一种使用方法语法,另一种使用查询语法。您可以通过使用SQL Profiler来确定查询运行时的确切情况。PS - LINQ的“要点”是您可以轻松地进行查询操作,而无需离开代码/VB-land。

谢谢,但从那里我看不到它讨论.Count,在使用express的时候所以没有访问分析器(必须花钱)...PS我收到了你的PS,应该说“或者我没有理解LINQ的工作方式” - spacemonkeys

1
一个重要的事情是,你提供的代码将能够与各种数据源一起使用。希望它能以非常高效的方式完成这个任务,但不能完全保证。如果数据源是 SQL,那么它肯定会以高效的方式完成(转换为 SELECT COUNT(*) SQL 查询)。如果数据源是内存集合,那么它也会以高效的方式完成(调用 Count 属性)。如果数据源是可枚举对象而不是集合,那么它并不是很高效(在这种情况下,它需要读取所有内容并计算数量),但在这种情况下,没有更高效的方法。
在每种情况下,它都以最高效的方式完成了相同的概念操作,而无需担心细节。计数不是什么大问题,但在更复杂的情况下就不同了。
在某种程度上,当你说“在我看来,SQL 返回所有行并对行数进行计数”时,你是正确的。从概念上讲,查询确实是这样做的,但实现可能有所不同。与 SQL 中的实际查询不匹配的字面解释相比,可以选择最有效的方法。

谢谢Jon,我认为在过去一个月左右使用LinQ的过程中学到的一件事情就是不要假设产生的SQL是什么(尽可能远离任何非iQueryable对象类型)。 - spacemonkeys
没错。实际上有时候我会查看生成的SQL语句,发现它有点奇怪,但是当我深入到下一个级别并查看查询计划时,就会发现LINQ产生的SQL比更明显的方法更好。值得一提的是,特别是对于更复杂或经常被访问的查询,查看所生成的SQL非常重要,因为你可以通过适当的索引和统计信息来优化它。 - Jon Hanna

0

我认为你没有理解Linq与SQL的关键之处,因为它具有延迟绑定,搜索是在需要时进行的,所以当你说需要计数时,会创建一个查询。

在此之前,Linq for SQL会创建表达式树,当你需要时会将其“翻译”成SQL....

http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx http://msdn.microsoft.com/en-us/netframework/aa904594.aspx

如何调试,请看 Scott http://weblogs.asp.net/scottgu/archive/2007/07/31/linq-to-sql-debug-visualizer.aspx alt text
(来源: scottgu.com)


那回答了上面的问题吗? - spacemonkeys
抱歉,我提出问题的原因是当我在“Dim query =(From o In data.Addresses Select o.Name).Count”上放置调试器或.string时,我得到了结果为2的结果,而当我对另一个查询执行相同操作时,我得到了预期的“select count(*)”sql,所以我倾向于后者更好....但由于我无法访问分析器,我无法确定。 - spacemonkeys
尝试在上下文对象上使用日志记录... http://www.codeproject.com/KB/linq/LINQ2Log4Net.aspx - salgo60
最好的学习工具是LinqPad http://www.linqpad.net/或者使用调试窗口 var sw = new System.IO.StringWriter(); db.Log = sw;请参阅 http://damieng.com/blog/2008/07/30/linq-to-sql-log-to-debug-window-file-memory-or-multiple-writers - salgo60
1
另一个Stack Overflow条目讨论Count的性能问题。 - salgo60

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接