2010-01-27 78 views
5

作爲一名初級開發人員,您曾經毆打過您的其中一件事是您永遠不會在數據集上執行「SELECT *」操作,因爲由於多種原因它不可靠。因爲移動到Linq(首先Linq到SQL,然後是實體框架),我想知道Linq等價物是否同樣被皺起了眉頭?Linq no-noes - 抓住所有類似sql的選擇?

var MyResult = from t in DataContext.MyEntity 
       where t.Country == 7 
       select t; 

我們是否應該選擇到一個匿名類型只有我們想要明確提到的領域,或者是趕上現在所有的選擇,因爲多餘的東西了LinqToSql等人接受周圍的數據,他們提供?

問候

+2

那些說你應該*永遠不會*,*永遠*做$ x的人和那些總是**做$ x的人一樣無知。 – 2010-01-27 14:03:33

+0

噢,我完全同意,但它*是*黃金法則之一... – Moo 2010-01-27 14:41:28

回答

5

這不是皺眉,它取決於你的用例。如果你想更新結果並堅持下去,那麼你應該選擇t,但是如果你不想這樣做,只是查詢顯示目的,你可以通過選擇你想要的屬性使其更有效:

var MyResult = from t in DataContext.MyEntity 
       where t.Country == 7 
       select new { t.Prop1, t.Prop2 }; 

這是有幾個原因。匿名類型的人口稍快,但更重要的是它disables change tracking ...因爲你不能堅持匿名類型,所以不需要跟蹤對它的更改。

Here's an excellent rundown of the common performance areas like this這很棒,當開始。它還包括我剛剛描述的更改跟蹤的更深入的解釋。

1

select t在這種情況下S選擇從一個已知類型的所有字段。它是強類型的,不太受在SQL中發現的相同錯誤的影響。

例如,在SQL

INSERT INTO aTable 
SELECT * FROM AnotehrTable 

可能會失敗,如果AnotherTable改變,但是Linq中/ .NET這種情況不會出現。

如果您要加入多個表格,那麼您無法在Linq中執行select *,您將不得不創建一個匿名類型,其中包含所有類型。

0

我會說你在做什麼是相當於SELECT *聲明。最好只返回所需的字段,例如

var myResult = from t in DataContext.MyEntity 
       where t.Country == 7 
       select new T 
       { 
        Field1 = t.Field1, 
        Field2 = t.Field2 
       } 
+0

如果您想在MyEntity中使用Everywhere,該怎麼辦?你會創建一個與MyEntity相同的匿名類型嗎? – cjk 2010-01-27 14:01:24

+1

我會認爲(沒有測試),返回噸OP作爲建議,會爲你做這個? – James 2010-01-27 14:04:05

0

你應該明確說明你想要選擇什麼。如果你選擇全部,你仍然需要的數據量比你需要的還要多,而且隨着新事物的增加,你也會不必要地拖拽這些數據。一般來說,最好的做法是隻提取你需要的東西。

0

使用LINQ不會減輕獲取額外字段的性能。

但是,它是不可能使用LINQ to SQL生成SELECT * FROM ...。 您的代碼將生成一個SELECT語句,該語句顯式地命名模型中定義的所有列;它會忽略對數據庫的任何更改。

但是,性能仍然是一個問題,所以如果您只使用某些列,則應該使用匿名類型。

0

可能需要按照示例進行操作,特別是如果需要執行的操作是對行的更改。

在SQL select *中與linq不同,因爲linq將始終返回相同數量的列(如在dbml中定義的那樣)。

1

避免SELECT *的原因是底層數據庫可能會更改,因此列順序可能會更改,這可能會導致數據訪問層出現錯誤。

你不是從你的數據庫執行SELECT *,你只是說你想要「t」以及它隨之而來的一切。如果那真的是你需要的,那沒有什麼不妥。