LINQ中最难或者最容易被误解的方面是什么?

282

背景:在接下来的一个月里,我将会就涉及到或至少包含C#中的LINQ这一话题发表三次演讲。我想知道哪些主题值得重点关注,基于人们可能难以理解的问题,或者他们可能存在误解的问题。除了作为使用表达式树远程执行查询(通常是IQueryable)的示例外,我不会特别谈论LINQ到SQL或实体框架。

那么,你发现过什么使LINQ难以理解的问题?你看到有哪些误解?例如可以是以下任何一种情况,但请不要限制你自己!

  • C#编译器如何处理查询表达式
  • Lambda表达式
  • 表达式树
  • 扩展方法
  • 匿名类型
  • IQueryable
  • 延迟与立即执行
  • 流式与缓存执行(例如OrderBy是延迟但缓存)
  • 隐式类型的局部变量
  • 阅读复杂的泛型签名(例如Enumerable.Join

3
我很想知道你们什么时候会进行这些演讲,以及是否有在线观看的方式。 - Mark Heath
2
第一场演讲:10月30日哥本哈根,希望能录制整个过程。(全天!) 第二场演讲:11月19日晚上伦敦,伦敦.NET用户组,可能会谈到Push LINQ。 第三场演讲:11月22日雷丁,开发者开发者日,60分钟内实现LINQ to Objects。 - Jon Skeet
1
下投票者请添加解释性评论。 - Jon Skeet
2
@Jon,抱歉,但我需要关闭这个。 - Tim Post
3
@Tim:说得对,反正它也没有得到更多的回答了。不过就我个人而言,我认为它最终还是很有建设性的——我确实觉得看看人们觉得什么棘手很有用。尽管如此,现在我可能不会再问这个问题了…… - Jon Skeet
显示剩余6条评论
42个回答

6
我认为LINQ中最被误解(或者应该说是未被理解)的方面是和自定义的LINQ提供程序。 我已经使用LINQ一段时间了,对于IEnumerable很熟悉,可以用LINQ解决大部分问题。
但是当我开始看和阅读关于IQueryable、表达式和自定义linq提供程序的内容时,我的头脑就开始晕转。如果你想看看LINQ到SQL是如何工作的,那么就会发现一些相当复杂的逻辑。
我期待着理解LINQ这个方面...

5

当执行查询时,var代表什么?

它是iQueryableiSingleResultiMultipleResult还是根据实现而改变。有人猜测在C#中使用(看起来像)动态类型与标准静态类型。


据我所知,var始终是具体的类(即使它是匿名类型),因此它永远不会是IQueryable、ISingleResult或以'I'开头的任何内容(以'I'开头的具体类无需应用)。 - Motti

5

很多人都不太理解嵌套循环的使用方法,其实很简单。

例如:

from outerloopitem in outerloopitems
from innerloopitem in outerloopitem.childitems
select outerloopitem, innerloopitem

+1,哇。那相当强大。 - Pretzel

4

group by 仍然让我感到困惑。

关于 延迟执行 的任何疑惑,都可以通过逐步执行一些简单的基于 LINQ 的代码并在观察窗口中进行调试来解决。


1
我发现为了好玩而实现相当多的LINQ to Objects真的很有帮助 :) 但是,确实有点令人困惑 - 特别是如果我有一段时间没有使用LINQ,我必须回到签名。同样,“join”与“join into”经常让我感到困惑... - Jon Skeet

4

我认为关于LINQ to SQL最大的误解是,你仍然需要了解SQL才能有效地使用它。

Linq to Sql还有一个被误解的问题是,为了让它工作,你仍然需要降低数据库安全性到荒谬的程度。

第三个问题是,如果将Linq to Sql与动态类(即在运行时创建类定义)一起使用,会导致大量的即时编译。这可能会严重影响性能。


4
已经熟悉SQL非常有益,因为Linq to SQL(和其他ORM)生成的一些SQL可能相当可疑,了解SQL可以帮助诊断此类问题。此外,Linq to SQL可以使用存储过程。 - Robert Harvey

4

已编译查询

由于IQueryable是方法调用,所以无法链式调用(尽管它们仍然只能被翻译成SQL!)这个事实几乎不可能解决,这会极大地违背DRY原则。我需要我的IQueryable用于即席查询,而这些查询没有经过编译(只有在重要场景下才有编译的查询)。但是,在编译查询中,我不能使用它们,而是需要再次编写常规查询语法。现在我要在两个地方做相同的子查询,如果有任何变化,都需要记得更新两个位置,等等。真是一个噩梦。


2

大多数人认为最容易误解的部分是把LINQ视为T-SQL的替代品。我的经理自认为是TSQL大师,不允许我们在项目中使用LINQ,甚至对微软发布这样的东西深恶痛绝!!!


2

如前所述,惰性加载和延迟执行。

LINQ to Objects和LINQ to XML(IEnumerable)与LINQ to SQL(IQueryable)有何不同?

如何在所有层中使用LINQ构建数据访问层、业务层和表示层……并提供一个好的示例。


我可以做前两个,但我不想尝试第三个,因为还没有确定“正确的方式”。 - Jon Skeet
+1,在你指出之前,我没有意识到LINQ-to-Objects和LINQ-to-XML是IEnumerable,而不是LINQ-to-SQL作为IQueryable,但这很有道理。谢谢! - Pretzel

2

事务(不使用TransactionScope)


2

懒加载。


类似于https://dev59.com/xHVC5IYBdhLWcg3wrDNd#215562 - Pratik

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