背景:在接下来的一个月里,我将做三次关于LINQ的演讲,或者至少将LINQ包含在c#的上下文中。我想知道哪些话题值得花相当多的精力,这取决于人们可能很难理解哪些话题,或者他们可能有错误的印象。我不会具体讨论LINQ to SQL或实体框架,只是作为如何使用表达式树(通常是IQueryable)远程执行查询的示例。

那么,你发现LINQ有什么难的地方吗?在误解方面你看到了什么?例子可能是以下任何一个,但请不要限制自己!

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


当前回答

编译查询

The fact that you can't chain IQueryable because they are method calls (while still nothing else but SQL translateable!) and that it is almost impossible to work around it is mindboggling and creates a huge violation of DRY. I need my IQueryable's for ad-hoc in which I don't have compiled queries (I only have compiled queries for the heavy scenarios), but in compiled queries I can't use them and instead need to write regular query syntax again. Now I'm doing the same subqueries in 2 places, need to remember to update both if something changes, and so forth. A nightmare.

其他回答

正如大多数人所说,我认为最被误解的部分是假设LINQ只是T-SQL的替代品。 我的经理认为自己是一个TSQL专家,他不让我们在项目中使用LINQ,甚至讨厌微软发布这样的东西!!

我仍然有问题的“让”命令(我从来没有发现一个用途)和SelectMany(我已经使用过,但我不确定我是否做对了)

对于LINQ2SQL:熟悉一些生成的SQL并编写可以转换为良好(快速)SQL的LINQ查询。这是知道如何平衡LINQ查询的声明性和它们需要在已知环境(SQL Server)中快速执行的真实性这一更大问题的一部分。

你可以得到一个完全不同的SQL生成查询通过改变一个很小很小的东西在LINQ代码。如果您正在基于条件语句创建表达式树(即添加可选的过滤条件),这可能特别危险。

我认为你应该更详细地关注LINQ中最常用的特性——Lambda表达式和匿名类型,而不是浪费时间在“难以理解”的东西上,这些东西在现实世界的程序中很少使用。

表达式<Func<T1, T2, T3,…>> and 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);
}