Linq表达式语法 - 如何使其更具可读性?

时间:2010-02-19 14:40:51

标签: linq lambda

我正在编写一些东西,使用Linq来组合我的数据库的结果,通过Linq2Sql和内存中的对象列表,以便找出我的哪些内存中对象与数据库中的内容匹配。

我在表达式和查询语法中都提出了查询。

表达式语法

var query = order.Items.Join(productNonCriticalityList,
    i => i.ProductID,
    p => p.ProductID,
    (i, p) => i);

查询语法

var query =
    from p in productNonCriticalityList
    join i in order.Items
        on p.ProductID equals i.ProductID
    select i;

我意识到我们已经使用表达式语法完成了所有代码的完成,并且我确实使用了更多。主要是因为创建可重复使用的过滤器代码块更容易,这些过滤器代码可以链接在一起形成更复杂的过滤器。

但是对于一个连接,后者对我来说似乎更具可读性,但也许这是因为我习惯于编写T-SQL。

所以,我错过了一个技巧,还是只是习惯了它?

5 个答案:

答案 0 :(得分:1)

这真的归结为偏好。有些人只是讨厌在代码中使用查询语法的想法。我非常欣赏查询语法,它是声明性的并且非常易读。就像你说的那样,第一个例子的可连接性是一件好事。我想我的钱会一直询问,直到我觉得我需要开始联系这个电话。

答案 1 :(得分:1)

我曾经有同样的感觉。现在我发现查询语法更容易读写,特别是当事情变得复杂时。尽管让我第一次输入它感到烦恼,但“让”以表达式语法中无法读取的方式做出精彩的事情。

答案 2 :(得分:1)

当我的复杂和表达式语法简单查询时,我更喜欢查询语法。

如果DBA要阅读C#代码以查看我们正在使用的SQL,他们将更容易理解和消化查询语法。

举一个简单的例子:
查询

var col = from o in orders
          orderby o.Cost ascending
          select o;

表达

var col2 = orders.OrderBy(o => o.Cost);

对我来说,表达式语法是一个更容易理解的选择。


另一个例子:
查询

var col9 = from o in orders
  orderby o.CustomerID, o.Cost descending
           select o;

表达

var col6 = orders.OrderBy(o => o.CustomerID).
          ThenByDescending(o => o.Cost);

如果查询是

,则两者都易于阅读和理解
//returns same results as above
var col5 = from o in orders
           orderby o.Cost descending
           orderby o.CustomerID
           select o;
//NOTE the ordering of the orderby's

这看起来有些令人困惑,因为字段的顺序不同,而且看起来有些倒退。


加入
查询

var col = from c in customers
          join o in orders on 
          c.CustomerID equals o.CustomerID
          select new 
          {
              c.CustomerID, 
              c.Name, 
              o.OrderID, 
              o.Cost
          };

表达式:

var col2 = customers.Join(orders, 
    c => c.CustomerID,o => o.CustomerID, 
    (c, o) => new 
        { 
            c.CustomerID, 
            c.Name, 
            o.OrderID, 
            o.Cost 
        }
    );

我发现查询更好。


根据手头的查询,我的摘要将使用看起来最简单,最快速的内容。没有使用的黄金法则。但是,如果有很多连接,我会使用Query语法。

答案 3 :(得分:1)

我同意其他回应者的意见,你提出的确切问题只是一个偏好问题。 Personaly,我混合了两种形式,这取决于我正在编写的特定查询更清楚。

如果我有一条评论,我会说查询看起来可能会加载订单中的所有商品。对于单个订单一次可能没什么问题,但是如果您循环执行大量订单,则可以更有效地一次性加载所有项目(您可能希望按日期或按日期进行过滤)顾客,或者其他什么)。如果您这样做,可以通过切换查询来获得更好的结果:

var productIds = (from p in productNonCriticalityList
                  orderby p.productID
                  select p.ProductID).Distinct();

var orderItems = from i in dc.OrderItems
                 where productIds.Contains(i.ProductID)
                    && // Additional filtering here.
                 select i;

初看起来有些倒退,但它可以避免加载所有订单商品以及发送大量查询。它的工作原理是因为where productIds.Contains(...)调用可以在SQL中转换为where i.ProductID in (1, 2, 3, 4, 5)。当然,您必须根据预期的订单商品数量和产品ID数量来判断。

答案 4 :(得分:0)

嗯,这两个陈述都是等价的。因此,您可以同时使用它们,具体取决于外围代码和更具可读性的代码。在我的项目中,我决定使用哪种语法取决于这两个条件。

就个人而言,我会在一行中编写表达式语法,但这是一个品味问题。