什么是最困难或最误解的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在语言中的SQL
parsing器。
大O符号 。 如果你不知道自己在做什么,LINQ使得编写O(n ^ 4)algorithm变得非常容易。
我认为, Lambda
expression式可以parsing为expression式树和匿名委托,因此您可以将相同的声明式lambda
expression式传递给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被误解的部分是它是一种语言扩展 ,而不是数据库扩展或构造。
LINQ
比LINQ 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(不同的连接方法)中更有效。
几件事。
- 人们认为Linq是Linq to SQL。
- 有些人认为他们可以开始用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代表什么?
它是iQueryable
, iSingleResult
, iMultipleResult
,还是根据实现进行更改? 有一些关于使用(似乎是)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)