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

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

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


当前回答

表达式<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);
}

其他回答

我知道延迟执行的概念现在应该被灌输给我了,但这个例子确实帮助我实际掌握了它:

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提供者之间的抽象何时泄漏。有些东西适用于对象,但不适用于SQL(例如,. takewhile)。一些方法可以被翻译成SQL (ToUpper),而另一些则不能。有些技术在对象中更有效,而其他技术在SQL中更有效(不同的连接方法)。

我想说,LINQ最容易被误解(或者不应该被理解?)的方面是IQueryable和自定义LINQ提供者。

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

但是当我开始看和阅读IQueryable,表达式和自定义linq提供程序时,它让我头晕目眩。如果您想了解一些相当复杂的逻辑,可以看看LINQ to SQL是如何工作的。

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

编译查询

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.

Explain why Linq does not handle left outer join as simple as in sql syntax. See this articles: Implementing a Left Join with LINQ, How to: Perform Left Outer Joins (C# Programming Guide) I got so disappointed when I came across this obstacle that all my respect for the language vanished and I decedid that it was just something that quickly would fade away. No serious person would want to work with a syntax that lacks these battlefield proven primitives. If you could explain why these sort of set operation are not supported. I would become a better and more openminded person.