2010-05-13 45 views

回答

7

,他們都將是從性能的角度等同。爲了便於閱讀,我傾向於將==放在.Equals()之上,但L2S的優點在於您可以使用其中之一,具體取決於您擁有的對象類型。

(我假設你的第二個說法是將訂單,而不是訂單對象)

+0

我多年沒有完成C#,但是這不是一個自動裝箱的東西,而不是L2S的東西?還是'=='取決於手頭的實例? – 2010-05-13 10:49:37

+0

@yar:沒有東西被裝箱,它是一個被訪問並轉換成SQL查詢的表達式樹。 – Aaronaught 2010-05-13 11:11:54

+0

@Aaronaught,是的,我現在明白了,希望我更仔細地看過代碼:)同時,我必須閱讀表達式樹,因爲我認爲「param」會得到評估在FirstOrDefault甚至獲得它之前。顯然這是不對的。 – 2010-05-13 11:29:16

9

我要去嘗試說服你:你提出

  • 的兩種方法給出相同的性能。
  • 至少有兩個與性能無關的原因,您應該更喜歡==
  • 您可以對代碼進行另一個單獨的改進,以減少出錯的可能性。

要查看性能將是相同的,請查看每種情況下生成的SQL。這個測試程序顯示瞭如何查看生成的SQL:

int orderId = 4; 
TextWriter textWriter = new StringWriter(); 
using (var dc = new DataClasses1DataContext()) 
{ 
    dc.Log = textWriter; 
    Order o1 = dc.Orders.FirstOrDefault(x => x.OrderId == orderId); 
    Order o2 = dc.Orders.FirstOrDefault(x => x.OrderId.Equals(orderId)); 
} 
string log = textWriter.ToString(); 

在每種情況下發送的SQL是一樣的,因爲你可以通過檢查日誌中看到:

SELECT TOP (1) [t0].[OrderId], [t0].[CustomerID], [t0].[Date], [t0].[Description] 
FROM [dbo].[Order] AS [t0] 
WHERE [t0].[OrderId] = @p0 

SELECT TOP (1) [t0].[OrderId], [t0].[CustomerID], [t0].[Date], [t0].[Description] 
FROM [dbo].[Order] AS [t0] 
WHERE [t0].[OrderId] = @p0 

關於是否使用==Equals,首先我建議使用==以提高可讀性。這是比較C#中兩個整數的習慣用法。

其次,使用==如果您提供不同(不兼容)類型的對象,則會發生編譯時錯誤。我認爲你的情況order有int類型,但我們假設有人寫了這段代碼,並且意外地發生了錯誤,其中orderOrder類型的變量而不是int。現在,讓我們比較在每種情況下會發生什麼:

Order order = new Order { OrderId = 4 }; 

x.OrderId.Equals(order) // This compiles, but you get an exception at runtime: 
         // Could not format node 'Value' for execution as SQL. 

x.OrderId == order  // Compile error: Operator '==' cannot be applied to 
         // operands of type 'int' and 'Order' 

這是更好地得到比編譯運行時錯誤的時間錯誤的,所以更喜歡在這種情況下使用==

最後,如果你只希望一個結果,你應該更喜歡使用SingleOrDefault代替FirstOrDefault因爲前者如果有發現,而不是隻返回前兩個匹配的對象會拋出異常。這額外的檢查將在性能上花費少量費用,但同樣可以讓您儘早發現錯誤。如果性能對您來說是一個關鍵問題,您應該考慮從數據庫中一次獲取多個對象,而不是一次刪除這些安全檢查,而不是一個對象。

因此,在總結我建議你使用這樣的:

Album album = db.Albums.SingleOrDefault(x => x.OrderId == orderId); 
+0

我的意思是這個訂單有int類型 – Sasha 2010-05-13 10:50:16

+3

.Equals()對類型太寬容了! – 2010-05-13 11:53:28

+0

+1偉大的答案馬克! – 2010-05-13 13:57:06

1

在大多數情況下,你應該得到同樣的結果。但是,有一個區別。

使用運算符Equals確定兩個對象實例是否相同。 運算符==確定兩個對象是否具有相同的值。

在這種情況下,我使用==運算符,因此它更具可讀性。

+3

+1好點。如果數據庫中的OrderId爲空,這個L2S是否會轉化爲'x.Order == null'?如果是這樣,'.Equals'調用將失敗,因爲左側沒有有效的對象。 – 2010-05-13 10:37:48

+0

'Int32','Guid'和所有其他值類型/原語具有'Equals'重載,它們具有相同類型的參數。當這會產生不同的結果時,唯一的實例是'orderId'參數實際上是與'Order.OrderId'屬性不同的類型。 – Aaronaught 2010-05-13 11:16:13

+0

這是錯誤的:Equals方法在System.Object上標記爲虛擬,並且可以被重寫。它應該和==一樣。 – 2010-05-13 11:17:52

0

它幾乎相同。如果你想只檢查值,那麼你應該使用

==

如果你想查詢的價值,以及它們是否相同情況下,或者不使用

的Equals

但是在這兩種情況下,結果時間幾乎相同。

+2

「等於」並不意味着參考平等。它可以在參數都是引用類型時執行引用檢查,但在這方面與'=='大體相同。如果你想引用相等,那麼你使用'object.ReferenceEquals'方法。 – Aaronaught 2010-05-13 11:18:19