db.Albums.FirstOrDefault(x => x.OrderId == orderId)
db.Albums.FirstOrDefault(x => x.OrderId.Equals(orderId))
db.Albums.FirstOrDefault(x => x.OrderId == orderId)
db.Albums.FirstOrDefault(x => x.OrderId.Equals(orderId))
,他們都將是從性能的角度等同。爲了便於閱讀,我傾向於將==放在.Equals()之上,但L2S的優點在於您可以使用其中之一,具體取決於您擁有的對象類型。
(我假設你的第二個說法是將訂單,而不是訂單對象)
我要去嘗試說服你:你提出
==
。要查看性能將是相同的,請查看每種情況下生成的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類型,但我們假設有人寫了這段代碼,並且意外地發生了錯誤,其中order
是Order
類型的變量而不是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);
我的意思是這個訂單有int類型 – Sasha 2010-05-13 10:50:16
.Equals()對類型太寬容了! – 2010-05-13 11:53:28
+1偉大的答案馬克! – 2010-05-13 13:57:06
在大多數情況下,你應該得到同樣的結果。但是,有一個區別。
使用運算符Equals
確定兩個對象實例是否相同。 運算符==
確定兩個對象是否具有相同的值。
在這種情況下,我使用==
運算符,因此它更具可讀性。
+1好點。如果數據庫中的OrderId爲空,這個L2S是否會轉化爲'x.Order == null'?如果是這樣,'.Equals'調用將失敗,因爲左側沒有有效的對象。 – 2010-05-13 10:37:48
'Int32','Guid'和所有其他值類型/原語具有'Equals'重載,它們具有相同類型的參數。當這會產生不同的結果時,唯一的實例是'orderId'參數實際上是與'Order.OrderId'屬性不同的類型。 – Aaronaught 2010-05-13 11:16:13
這是錯誤的:Equals方法在System.Object上標記爲虛擬,並且可以被重寫。它應該和==一樣。 – 2010-05-13 11:17:52
它幾乎相同。如果你想只檢查值,那麼你應該使用
==
如果你想查詢的價值,以及它們是否相同情況下,或者不使用
的Equals
但是在這兩種情況下,結果時間幾乎相同。
「等於」並不意味着參考平等。它可以在參數都是引用類型時執行引用檢查,但在這方面與'=='大體相同。如果你想引用相等,那麼你使用'object.ReferenceEquals'方法。 – Aaronaught 2010-05-13 11:18:19
我多年沒有完成C#,但是這不是一個自動裝箱的東西,而不是L2S的東西?還是'=='取決於手頭的實例? – 2010-05-13 10:49:37
@yar:沒有東西被裝箱,它是一個被訪問並轉換成SQL查詢的表達式樹。 – Aaronaught 2010-05-13 11:11:54
@Aaronaught,是的,我現在明白了,希望我更仔細地看過代碼:)同時,我必須閱讀表達式樹,因爲我認爲「param」會得到評估在FirstOrDefault甚至獲得它之前。顯然這是不對的。 – 2010-05-13 11:29:16