什么是最困难或最误解的LINQ的方面?

背景:在接下来的一个月里,我将在C#的上下文中进行三次关于或者至less包括LINQ的讨论。 我想知道哪些主题值得给予相当的关注,基于什么人可能会觉得难以理解,或者他们可能有什么错误的印象。 除了作为如何使用expression式树(通常是IQueryable )远程执行查询的例子之外,我不会专门讨论LINQ to SQL或entity framework。

那么,你对LINQ什么LINQ ? 你在误解中看到了什么? 例子可能是以下任何一种,但请不要限制自己!

  • C#编译器如何处理查询expression式
  • Lambdaexpression式
  • expression树
  • 扩展方法
  • 匿名types
  • IQueryable
  • 推迟与立即执行
  • stream与缓冲执行(例如,OrderBy被延迟,但被缓冲)
  • 隐式键入局部variables
  • 阅读复杂的通用签名(例如Enumerable.Join )

延迟执行

我知道现在延期执行的概念应该被殴打到我身上,但是这个例子确实帮助我实际掌握了这个概念:

 static void Linq_Deferred_Execution_Demo() { List<String> items = new List<string> { "Bob", "Alice", "Trent" }; var results = from s in items select s; Console.WriteLine("Before add:"); foreach (var result in results) { Console.WriteLine(result); } items.Add("Mallory"); // // Enumerating the results again will return the new item, even // though we did not re-assign the Linq expression to it! // Console.WriteLine("\nAfter add:"); foreach (var result in results) { Console.WriteLine(result); } } 

上面的代码返回以下内容:

 Before add: Bob Alice Trent After add: Bob Alice Trent Mallory 

这不仅仅是LINQ to SQL而且这些特性不仅仅是embedded在语言中的SQLparsing器。

大O符号 。 如果你不知道自己在做什么,LINQ使得编写O(n ^ 4)algorithm变得非常容易。

我认为, Lambdaexpression式可以parsing为expression式树和匿名委托,因此您可以将相同的声明式lambdaexpression式传递给IEnumerable<T>扩展方法和IQueryable<T>扩展方法。

花了太长时间才意识到许多LINQ扩展方法,例如Single()SingleOrDefault()等都有带lambdaexpression式的重载。

你可以做 :

 Single(x => x.id == id) 

不用说这个 – 一些糟糕的教程让我养成了习惯

 Where(x => x.id == id).Single() 

在LINQ to SQL中,我经常看到人们不理解DataContext,如何使用它以及如何使用它。 太多人没有看到它是一个工作单元对象的DataContext,而不是持久对象。

我已经看到很多次,人们试图单独DataContext /会话它/等,而不是每个操作一个新的时间。

然后在IQueryable被评估之前就抛弃了DataContext,但更多的是人们不理解IQueryable而不是DataContext。

我看到很多混淆的另一个概念是查询语法与expression式语法。 我将使用哪一个是最容易的,经常坚持使用Expression Syntax。 很多人最终还是没有意识到自己会产生同样的东西,毕竟Query被编译成expression式。

我认为LINQ被误解的部分是它是一种语言扩展 ,而不是数据库扩展或构造。

LINQLINQ to SQL多得多。

现在,我们大多数人都使用LINQ的集合,我们永远不会回去!

从2.0generics开始, LINQ是.NET最重要的特性,3.0是匿名types。

而现在我们有了Lambda,我不能等待并行编程!

我一个人肯定想知道我是否需要知道expression树是什么,为什么。

我对LINQ相当陌生。 这是我第一次尝试时偶然发现的事情

  • 将几个查询合并为一个
  • 在Visual Studio中有效地debuggingLINQ查询。

我最初并没有意识到的一点是,LINQ语法不需要IEnumerable<T>IQueryable<T>来工作,LINQ只是模式匹配。

替代文字http://bartdesmet.info/images_wlw/QIsIQueryabletheRightChoiceforMe_13478/image_thumb_3.png

这里是答案 (不,我没有写博客,Bart De Smet做了,他是我find的LINQ上最好的博主之一)。

我仍然遇到了“let”命令(我从来没有发现这个命令)和SelectMany(我曾经用过,但是我不确定我是否做得对)

了解Linq提供者之间的抽象何时泄漏。 有些东西在对象上工作,而不是在SQL上(例如.TakeWhile)。 有些方法可以翻译成SQL(ToUpper),而有些则不能。 有些技术在其他人更有效的SQL(不同的连接方法)中更有效。

几件事。

  1. 人们认为Linq是Linq to SQL。
  2. 有些人认为他们可以开始用Linq查询replace所有的foreach / logic,而不考虑这个性能影响。

好,由于需求,我写了一些expression的东西。 我不是百分之百满意博客和LiveWriter如何共谋格式化,但它现在会做…

无论如何,这里呢…我喜欢任何反馈,特别是如果有一些地方人们想要更多的信息。

在这里,它是或喜欢它…

一些错误消息,特别是从LINQ到SQL可能是相当混乱。 微笑

像其他人一样,我已经被延迟执行了几次。 我认为最令我困惑的是SQL Server查询提供程序,你可以做什么,不能做什么。

我还是很惊讶你不能在有时为空的十进制/金钱列上做Sum()。 使用DefaultIfEmpty()就是行不通的。 🙁

我认为在LINQ中应该包括一个很好的东西,那就是如何在性能方面让自己陷入困境。 例如,使用LINQ的count作为一个循环条件是真的,真的不聪明。

在第二种情况下,IQueryable同时接受Expression<Func<T1, T2, T3, ...>>Func<T1, T2, T3, ...> ,而不会给出关于性能下降的暗示。

这里是代码示例,演示了我的意思:

 [TestMethod] public void QueryComplexityTest() { var users = _dataContext.Users; Func<User, bool> funcSelector = q => q.UserName.StartsWith("Test"); Expression<Func<User, bool>> expressionSelector = q => q.UserName.StartsWith("Test"); // Returns IEnumerable, and do filtering of data on client-side IQueryable<User> func = users.Where(funcSelector).AsQueryable(); // Returns IQuerible and do filtering of data on server side // SELECT ... FROM [dbo].[User] AS [t0] WHERE [t0].[user_name] LIKE @p0 IQueryable<User> exp = users.Where(expressionSelector); } 

我不知道它是否符合误解 – 但对我来说,根本不为人知。

我很高兴了解DataLoadOptions以及如何在进行特定查询时控制哪些表join。

在这里看到更多的信息: MSDN:DataLoadOptions

我会说最被误解(或应该是不明白的?)方面的LINQ是IQueryable自定义的LINQ提供商

我已经使用了一段时间的LINQ,并且在IEnumerable世界中完全适应,并且可以用LINQ解决大多数问题。

但是当我开始查看和阅读关于IQueryable,expression式和自定义linq提供程序时,它使我的头脑旋转。 看看LINQ to SQL如何工作,如果你想看到一些非常复杂的逻辑。

我期待了解LINQ的这一方面…

正如大多数人所说,我认为最误解的部分是假设LINQ只是T-SQL的替代品。 我认为自己是TSQL专家的经理不会让我们在我们的项目中使用LINQ,甚至不喜欢MS发布这样的事情!

查询执行时var代表什么?

它是iQueryableiSingleResultiMultipleResult ,还是根据实现进行更改? 有一些关于使用(似乎是)dynamictypes与C#中的标准静态types的猜测。

嵌套循环是多么容易,我不认为每个人都能理解。

例如:

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

group by依然让我头晕目眩。

任何有关延迟执行的混淆都应该能够通过简单的基于LINQ的代码来实现,并在监视窗口中播放。

编译查询

事实上,你不能链接IQueryable因为它们是方法调用(尽pipe没有别的,但SQL可转换!),几乎不可能解决它是mindboggling和创build一个巨大的DRY违反。 我需要我的IQueryable的临时编辑,我没有编译查询(我只编译查询重的情况下),但在编译查询我不能使用它们,而是需要再次编写常规查询语法。 现在我在2个地方做同样的子查询,如果有什么变化,需要记住更新,等等。 一个噩梦。

我认为关于LINQ to SQL的第一个误解是,为了有效地使用它,你仍然需要知道SQL。

另一个关于Linq to Sql的误解是你仍然必须将数据库的安全性降到荒谬的地步,才能使其工作。

第三点是,使用Linq to Sql和Dynamic类(意味着类定义是在运行时创build的)会导致大量的即时编译(just-in-time compiling)。 这绝对可以杀死性能。

懒加载。

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

LINQ to Objects和LINQ to XML(IEnumerable)与LINQ to SQL(IQueryable)的不同之处在于,

如何用LINQ在所有层中构build数据访问层,业务层和表示层….并且是一个很好的例子。

正如大多数人所说,我认为最误解的部分是假设LINQ只是T-SQL的替代品。 我认为自己是TSQL专家的经理不会让我们在我们的项目中使用LINQ,甚至不喜欢MS发布这样的事情!

事务(不使用TransactionScope)