2010-02-19 14 views
4

我正在编写一些使用Linq将来自我的数据库的结果,Linq2Sql和一个内存中对象列表的结果进行合并,以便找出哪些内存中的对象与数据库上的某些内容匹配。Linq表达式语法 - 如何使它更具可读性?

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

表达式语法

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。

那么,我是否错过了一个把戏,或者它只是习惯了吗?

回答

1

我同意其他答复者的意见,你问的确切问题只是一个偏好问题。个人而言,我将两种形式混合使用,具体取决于我正在编写的具体查询更清楚。

如果我有一个评论,但我会说,查询看起来像它可能会加载订单中的所有项目。对于一次订单而言,这可能是正确的,但是如果您正在循环大量订单,那么一次加载所有项目的所有项目可能会更加高效(您可能希望按日期进行额外筛选或客户,或者其他)。如果你这样做,你可能会被周围切换查询得到更好的结果:

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号来判断。

+0

我order.Items已经在内存中,但我知道你在说什么:) – 2010-02-19 15:19:39

0

那么,这两个陈述是等价的。所以你可以把它们都看成两个,这取决于代码的超越性和可读性。在我的项目中,我根据这两个条件决定使用哪种语法。

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

1

它真的都归结于偏好。有些人在代码中讨厌像查询语法这样的想法。我喜欢查询语法,它是声明性的,而且非常可读。就像你说的那样,第一个例子的可链接性是一件好事。我想我的钱我会保持查询,直到我觉得我需要开始链接电话。

1

我曾经以同样的方式感受。现在我发现查询语法更容易读写,特别是当事情变得复杂时。尽管它让我第一次输入它,'让'以无法在Expression Syntax中读取的方式来做很棒的事情。

+0

@Ruben:说真的,别担心;我真的不那么强烈。你是对的,它没有提供更多的东西,我只是觉得(轻微)其他的副本是删除的副本。由于我没有upvotes,现在没有太大的收获。让我们删除这些评论,并忘记它 - 更好的问题来回答:) – pdr 2010-02-19 17:53:49

1

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

如果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语法。