What's the hardest or most misunderstood aspect of LINQ?
背景:下个月,我将在
那么,你觉得
C# 编译器如何处理查询表达式- lambda表达式
- 表达式树
- 扩展方法
- 匿名类
IQueryable - 延期与立即执行
- 流式处理与缓冲执行(例如,orderby被延迟但被缓冲)
- 隐式类型的局部变量
- 读取复杂的通用签名(例如Enumerable.Join)
延迟执行
我知道到目前为止,延迟执行的概念应该已经打动我了,但这个例子确实帮助我实际掌握了它:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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(" After add:"); foreach (var result in results) { Console.WriteLine(result); } } |
上面的代码返回以下内容:
1 2 3 4 5 6 7 8 9 10 | Before add: Bob Alice Trent After add: Bob Alice Trent Mallory |
不仅有
大O符号。Linq使编写O(n^4)算法变得非常容易,如果你不知道自己在做什么,就不会意识到它。
我认为一个
我花了很长时间才意识到许多LINQ扩展方法(如
你可以做到:
1 | Single(x => x.id == id) |
不用这么说-一些糟糕的指导让我养成了这样做的习惯
1 | Where(x => x.id == id).Single() |
在LinqToSQL中,我经常看到人们不理解DataContext、如何使用它以及如何使用它。太多人看不到DataContext是什么,它是工作对象的一个单元,而不是持久对象。
我见过很多时候,人们试图单独使用一个数据上下文/会话it/etc,而不是为每个操作留出新的时间。
然后在对iqueryable进行评估之前处理DataContext,但这更像是一个不了解iqueryable的人的道具,而不是DataContext。
我看到的另一个概念是查询语法与表达式语法。在这一点上,我将使用最简单的方法,通常坚持表达式语法。很多人仍然不知道他们最终会产生相同的东西,毕竟查询是编译成表达式的。
我认为LINQ被误解的部分是它是一个语言扩展,而不是数据库扩展或构造。
既然我们中的大多数人已经在托收上使用了
现在我们有了lambda,我等不及要并行编程了!
我个人肯定想知道我是否需要知道什么是表达树,为什么。
我最初没有意识到的是Linq语法不需要
alt text http://barddesmet.info/images_wlw/qisiqueryabletherlightchoiceforme_13478/image_thumb_3.png
这是答案(不,我没有写那个博客,巴特·德斯密特写的,他是我在Linq找到的最好的博客之一)。
我对林肯还比较陌生。这是我第一次尝试时遇到的问题
- 将多个查询合并为一个查询
- 在Visual Studio中有效地调试LINQ查询。
了解LINQ提供者之间的抽象何时泄漏。有些东西对对象有效,但对SQL无效(例如takewhile)。有些方法可以转换成SQL(toupper),而其他方法则不能。有些技术在对象中更有效,而其他方法在SQL中更有效(不同的连接方法)。
我仍然无法使用"let"命令(我从未找到该命令的用途)和selectmany(我使用过该命令,但我不确定是否正确)
两件事。
好吧,由于需要,我写了一些表达的东西。我对Blogger和LiveWriter密谋将其格式化并不完全满意,但现在就这样……
不管怎样,这是…我喜欢任何反馈,尤其是在有些地方人们需要更多的信息。
就在这里,喜欢还是讨厌…
有些错误消息,特别是从LINQ到SQL的错误消息可能非常令人困惑。露齿而笑
我和其他人一样,被延期执行的死刑咬了好几次。我认为对我来说最令人困惑的事情是SQL Server查询提供程序,以及您可以和不能用它做什么。
你不能在小数/货币列上做sum()这个事实仍然让我惊讶,因为它有时是空的。使用defaultifempty()只是不起作用。:(
我认为在Linq中要介绍的一个很好的事情是如何让自己在性能方面陷入困境。例如,使用Linq的Count作为循环条件真的很不明智。
iqueryable接受这两种情况,即
下面是代码示例,它演示了我的意思:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [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,以及在进行特定查询时如何控制哪些表被联接。
有关详细信息,请参阅此处:msdn:dataloadOptions
正如大多数人所说,我认为最被误解的部分是假设Linq只是T-SQL的替代品。我的经理认为自己是TSQL专家,他不会让我们在项目中使用LINQ,甚至讨厌MS发布这样的东西!!!!
我想说的是最被误解的(还是不被理解的?)LINQ的方面是可查询的和自定义的LINQ提供者。
我用LINQ已经有一段时间了,在IEnumerable的世界里非常舒服,可以解决大多数LINQ的问题。
但是当我开始查看和阅读关于iqueryable、表达式和定制Linq提供者的内容时,它让我头晕目眩。如果您希望看到一些非常复杂的逻辑,请看一下LinqToSQL是如何工作的。
我期待着了解Linq的这一方面…
执行查询时var代表什么?
是
我认为每个人都不理解嵌套一个循环是多么容易。
例如:
1 2 3 | from outerloopitem in outerloopitems from innerloopitem in outerloopitem.childitems select outerloopitem, innerloopitem |
已编译查询
您不能链接
任何关于延迟执行的混淆都应该能够通过单步执行一些简单的基于LINQ的代码并在监视窗口中四处播放来解决。
我认为关于Linq to SQL的1误解是,为了有效地利用它,您仍然需要了解SQL。
关于LinqToSQL的另一个误解是,为了使其正常工作,您仍然需要将数据库安全性降低到荒谬的程度。
第三点是,使用LINQ to SQL和动态类(意味着类定义是在运行时创建的)会导致大量的实时编译。这绝对会扼杀性能。
延迟加载。
事务(不使用TransactionScope)
如前所述,延迟加载和延迟执行
Linq to对象和Linq to XML(IEnumerable)与Linq to SQL(IQueryable)的区别
如何在所有层中使用LINQ构建数据访问层、业务层和表示层……这是一个很好的例子。
正如大多数人所说,我认为最被误解的部分是假设Linq只是T-SQL的替代品。我的经理认为自己是TSQL专家,他不会让我们在项目中使用LINQ,甚至讨厌MS发布这样的东西!!!!
解释为什么Linq不像SQL语法那样简单地处理左外部联接。请参阅本文:使用LINQ实现左联接,如何:执行左外部联接(C编程指南)当我遇到这个障碍时,我非常失望,以至于我对语言的所有尊重都消失了,我觉得这只是一种很快就会消失的东西。没有一个严肃的人愿意使用缺乏这些战场证明的原始语的语法。如果您可以解释为什么不支持这些类型的设置操作。我会成为一个更好更开明的人。
我觉得"创造表情树"很难。有很多事情困扰着我w.r.t你可以用linq,linq to sql和ado.net。
Linq to SQL如何翻译它!
假设我们有一个表,其中有3个字段:a、b&c(它们是整数,表名是"table1")。
我是这样展示的:
[a,b,c]
现在我们想得到一些结果,例如:
[X=A,Y=B+C]
我们有这样一个班级:
1 2 3 4 5 6 7 8 9 10 11 | public class Temp { public Temp(int x, int y) { this.X = x; this.Y = y; } public int X { get; private set; } public int Y { get; private set; } } |
然后我们这样使用它:
1 2 3 4 5 |
生成的SQL查询是:
1 2 | SELECT [t0].[A] AS [x], [t0].[B] + [t0].[C] AS [y] FROM [Table1] AS [t0] |
它转换温度的系数。它知道我想要"row.b+row.c"(甚至更多…)放在类构造函数的"y"参数上!
这些翻译对我很不感兴趣。我喜欢这样,我认为写这样的翻译(Linq to something)有点难!
当然!这是一个坏消息:LINQtoEntities(4.0)不支持带有参数的构造函数。(为什么不呢?)
我认为您应该更详细地关注linq最常用的特性——lambda表达式和匿名类型,而不是浪费时间在"难以理解"的东西上,这些东西在现实世界的程序中很少使用。
哪个更快,使用tsql存储过程内联linq to sql或linq to sql
…在某些情况下,使用服务器端(存储过程)或客户端(内联LINQ)查询更好。
理解语法"magic"。如何将理解语法转换为方法调用以及选择了什么方法调用。
例如,如何:
1 2 3 4 |
转换为方法调用。
对于Linq2SQL:了解一些生成的SQL,并编写转换为良好(快速)SQL的Linq查询。这是更大的问题的一部分,即知道如何平衡LINQ查询的声明性性质与它们需要在已知环境(SQL Server)中快速执行的现实性。
通过更改LINQ代码中的一个小东西,您可以得到一个完全不同的SQL生成的查询。如果要基于条件语句(即添加可选筛选条件)创建表达式树,则可能会特别危险。
我发现查询表达式语法只支持LINQ功能的一个子集有点令人失望,因此您不能避免不时地链接扩展方法。例如,不能使用查询表达式语法调用
一个关于LINQ的讨论可以包括一些实用的指导原则,说明何时喜欢一种语法而不是另一种,以及如何混合它们。
当然,这不是"最困难的",而是要添加到列表中的内容:
1 | ThenBy() extension method |
不看它的实现,我最初对它是如何工作感到困惑。每个人都很清楚逗号分隔的排序字段在SQL中是如何工作的——但就表面价值而言,我怀疑Thenby是否会做我真正希望它做的事情。它怎么能"知道"前一个排序字段是什么——看起来它应该是。
我现在要去研究它…
我发现很难找到关于匿名类型的明确信息,特别是关于Web应用程序的性能。此外,我还将在查询和性能相关主题中建议更好和实用的lamda表达式示例和"如何"部分。
希望我的简要清单能有所帮助!
您不能链接iQueryable,因为它们是方法调用(但除了SQL可翻译之外,其他什么都没有!)几乎不可能围绕它工作,这是令人难以置信的,并造成了对干燥的巨大破坏。我需要我的iqueryable用于没有编译查询的即席查询(我只有针对重场景编译的查询),但是在编译的查询中,我不能使用它们,而是需要再次编写常规查询语法。现在,我在两个地方执行相同的子查询,需要记住,如果发生变化,需要同时更新这两个查询,等等。噩梦
我打赌几乎有人知道:您可以在LINQ查询中使用内联IFS。像这样:
1 2 3 4 | var result = from foo in bars where ( ((foo.baz != null) ? foo.baz : false) && foo.blah =="this") select foo; |
我想你也可以插羊羔肉,尽管我没有试过。