代码之家  ›  专栏  ›  技术社区  ›  Antony Scott

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

  •  4
  • Antony Scott  · 技术社区  · 15 年前

    我正在写一些将使用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;
    

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

    但是对于一个join,后者对我来说似乎更可读,但这可能是因为我习惯于编写T-SQL。

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

    5 回复  |  直到 15 年前
        1
  •  1
  •   Damian Powell    15 年前

    我同意其他回应者的看法,你所问的确切问题只是一个简单的偏好问题。就个人而言,我将这两种形式混合在一起,这取决于对于我正在编写的特定查询,哪种形式更清晰。

    不过,如果我有一条评论,我会说查询看起来可能从订单中加载所有项目。对于一个订单来说,这一点可能很好,但是如果您循环处理大量订单,那么一次加载所有项目可能会更有效(您可能希望根据日期或客户或其他方式进行额外筛选)。如果这样做,您可以通过切换查询来获得更好的结果:

    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(...) 呼叫可以转换为 where i.ProductID in (1, 2, 3, 4, 5) 在SQL中。当然,您必须根据订单项目的预期数量和产品ID的数量来判断它。

        2
  •  1
  •   Jeremy B.    15 年前

    一切都取决于个人喜好。有些人只是讨厌在代码中使用类似查询的语法。我个人很欣赏查询语法,它是声明性的,而且可读性很强。不过,正如您所说,第一个示例的可链接性是一件很好的事情。我想为了我的钱,我会一直询问,直到我觉得我需要开始链接电话。

        3
  •  1
  •   pdr    15 年前

    我以前也有同样的感觉。现在我发现查询语法更容易读写,特别是当事情变得复杂时。尽管第一次输入它让我很恼火,“让我们”用在表达式语法中不可读的方式来做一些奇妙的事情。

        4
  •  1
  •   Simon Hughes    15 年前

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

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

    我觉得这个问题比较好。


    考虑到手头的查询,我的摘要将使用任何看起来最容易和最快理解的内容。没有黄金法则可供使用。但是,如果有很多连接,我将使用查询语法。

        5
  •  0
  •   AxelEckenberger    15 年前

    好吧,这两种说法是等价的。因此,您可以根据代理代码和更可读的代码来同时使用它们。在我的项目中,我根据这两个条件决定使用哪种语法。

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