【问题标题】:Addicted to LINQ [closed]沉迷于 LINQ [关闭]
【发布时间】:2008-11-04 15:15:27
【问题描述】:

好吧,我越用 LINQ,我就越喜欢它!我最近发现自己在工作中使用一些遗留代码。它是您经典的 DataSet 和 DataTable 丰富的应用程序。好吧,当添加一些功能时,我发现自己真的只想查询 DataTable 的行以获得我正在寻找的结果。

让我重复一遍……我只是想向 Rows 集合询问我需要什么,而不是循环并添加到临时集合中。没有循环,没有临时变量,只要给我我想要的。

var customerOrderIds = table.Rows.Cast<DataRow>()
   .Where(x => (string)x["CUSTOMER_ID"] == customerId)
   .Select(x => (string)x["CUSTOMER_ORDER_ID"])
   .Distinct();

我的问题是,这是否是一件好事,还是被 LINQ 冲昏了头脑? 在我看来,这种从集合中提取数据子集的声明式风格确实是一件好事,最终更具可读性。但话又说回来,也许我只是被迷住了:)

【问题讨论】:

    标签: .net linq


    【解决方案1】:

    另一个观察;如果您不使用类型化数据集,您可能还想了解Field&lt;&gt; 扩展方法:

        var customerOrderIds = table.Rows.Cast<DataRow>()
           .Where(x => x.Field<string>("CUSTOMER_ID") == customerId)
           .Select(x => x.Field<string>("CUSTOMER_ORDER_ID"))
           .Distinct();
    

    或者使用查询语法:

       var customerOrderIds = (
            from row in table.Rows.Cast<DataRow>()
            where row.Field<string>("CUSTOMER_ID") == customerId
            select row.Field<string>("CUSTOMER_ORDER_ID")
         ).Distinct();
    

    我并不是说它是更好或更坏 - 只是另一个可行的选择。

    (其实我不太用DataTable,所以YMMV)

    【讨论】:

    • 我不知道 Field...甜 - 我想你只是增加了我的瘾
    • (sfx:疯狂地检查书,看看我是否曾经知道这一点......)呼......令人惊讶的是,一个人在一年中忘记了什么:)
    【解决方案2】:

    对我来说似乎不错 - 尽管我会尝试使用强类型数据集,这会使 LINQ 查询看起来更加愉快。

    但是,是的,LINQ 是一个非常好的东西 - 与进程外 LINQ 提供程序相比,LINQ to Objects(以及用于 XML 和 DataSets 的周边技术)具有惊人的可预测性。 (它不像 LINQ to SQL 那样性感,但更广泛地适用于 IMO。)

    【讨论】:

      【解决方案3】:

      查询看起来不错。

      我想指出两件小事。

      没有循环

      System.Linq.Enumerable 方法对 IEnumerable(T) 合约进行操作,这几乎总是意味着循环 - O(N) 解决方案。这有两个含义:

      • 优先选择 Any() 而不是 Count() > 0 。 Any() 是 O(1)。 Count() 是 O(N)。
      • 联接...所有联接都是嵌套循环 O(M*N)。

      .Cast

      .Cast 对 DataTable.Rows 非常有效(所有这些对象都是行,所以 cast 总是成功的)。对于异构集合,请注意 .OfType() - 它会过滤掉任何无法转换的项目。

      最后,请注意查询在被枚举之前不会执行!您可以通过 foreach、ToList、ToArray、First、Single 等强制枚举。

      【讨论】:

      • 你对循环是绝对正确的......我想我最感兴趣的是我不是循环的人。如果没有性能影响,我发现可读性和可维护性要高得多。关于使用 Any() 的绝妙花絮!
      • 实际上,Count() 将检查 ICollection 的源并使用 .Count - 但是,这不适用于带有迭代器块的任何东西......所以 source.Where(. ..).Count() 可能很昂贵,但 source.Count() 可能很便宜。但最佳实践确实是 Any()
      【解决方案4】:

      就个人而言,由于数据表本身没有能力进行选择不同,我会说这还不错。

      我可能会问,是否有任何方法最终可以使用对象而不是数据表,因为我认为未来的开发人员会更容易理解。

      【讨论】:

        【解决方案5】:

        你根本不会得意忘形。在 LINQ to DataSets 上发布了实际作品。拥有如此清晰、声明性的对象查询使代码的可维护性变得更加容易。但是你必须记住,在你过滤数据的时候,所有的数据都已经被拉回来了。您可能需要考虑将过滤添加到 DataSet 查询的 SQL 中。

        【讨论】:

          【解决方案6】:

          LINQ 只是为您编写“循环/临时变量”代码。 LINQ 可帮助您更快地编写代码(并且更具可读性)。

          你的代码很好。

          【讨论】:

            【解决方案7】:

            连接(使用 join 关键字,但不使用 from 关键字)使用字典进行匹配,因此是 O(M+N)

            group by 也是如此,但以下不是:

            from x in Xs
            from y in Ys
                .Where(o => o == x)
            select new
            {
                x,
                y
            }
            

            这是O(M*N)

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2010-12-20
              • 1970-01-01
              • 2011-07-24
              • 2011-06-27
              • 1970-01-01
              • 2022-01-19
              • 1970-01-01
              相关资源
              最近更新 更多