[c#] 什么是最困难或最误解的LINQ的方面?



Answers

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

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
Question

背景:在接下来的一个月中,我将在C#的上下文中提供三个有关或至少包含LINQ的讨论。 我想知道哪些主题值得给予相当多的关注,基于人们可能会觉得难以理解的内容,或者他们可能会误认为什么。 除了作为如何使用表达式树(通常为IQueryable )远程执行查询的示例之外,我不会专门讨论LINQ to SQL或实体框架。

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

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



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

我一直在使用LINQ一段时间,并且在IEnumerable世界中完全适应,并且可以解决LINQ的大部分问题。

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

我期待理解LINQ的这一方面......




事务(不使用TransactionScope)




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

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

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




一些错误消息,尤其是从LINQ到SQL的错误消息可能会让人感到困惑。 微笑

像其他人一样,我一直被延迟执行所困扰。 我认为对我来说最令人困惑的是SQL Server查询提供程序以及你可以做什么和不可以做什么。

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




我仍然遇到了“let”命令(我从来没有找到它的用处)和SelectMany(我曾用它,但我不确定我是否做得对)




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

你可以做 :

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

不需要说这个 - 一些糟糕的教程让我养成了习惯

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



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);
}



几件事情。

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



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

LINQ远远超过LINQ to SQL

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

自从2.0中的泛型以及3.0中的匿名类型以来, LINQ是.NET最重要的特性。

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




大O符号 。 如果你不知道自己在做什么,LINQ使得写入O(n ^ 4)算法变得非常容易,而不会意识到它。




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

  • 将几个查询合并成一个
  • 在Visual Studio中有效调试LINQ查询。



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

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

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




var代表什么时候执行查询?

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




group by依然让我头晕目眩。

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




Links



Tags

c# c#   linq   c#-3.0