2010-02-19 57 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語法。