2014-09-19 97 views
1

我目前正在使用AdventureWorks示例數據庫和LinqPad進行操作,以抓取一些想法。Linq結果以不同的順序顯示

這是有問題的查詢:

SalesOrderHeaders.GroupBy (soh => new {soh.CustomerID, soh.BillToAddressID}) 
       .Where(soh => soh.Skip(1).Any()) 
       .Dump(); 

當時的想法是找到基於一些標準重複,然後顯示他們除了第一組數據。結果應從表格中刪除。

執行查詢後,我得到的結果A) First Result

再次執行查詢後,我得到的結果B) enter image description here

我不關心查詢的正確的結果,但對結果集的排序。只有這兩種可能性存在,並且它們在查詢的每次運行中交替。 當然,我可以通過鍵來訂購,但我更感興趣,爲什麼這會發生?爲什麼命令chaning /交替?

+1

您的期望導致了一般原則,即向用戶呈現的數據應該是有序的,即使沒有其他理由對其進行排序或行之間的邏輯排序也是如此。 (或者當然,這不適用於像LINQPad和SSMS這樣的開發者工具。) – 2014-09-19 18:52:14

回答

6

Sql server select查詢的結果集順序不確定。這只是sql server的工作原理,並不是linq或linqpad中的一個bug。正如您所指出的那樣,您的查詢獲得確定性結果的唯一方法是使用OrderBy子句。

編輯:如果多次運行查詢,請在SSMS中獲取相同的結果,請參閱this。這篇文章解釋了爲什麼如果你多次執行一個查詢可能會得到相同的結果,爲什麼你不應該依賴它。

+0

還有另一個我剛發現的解決方法。取出生成的SQL代碼並在SSMS中執行它。然後訂單被設置。 但是爲什麼有兩個不同的結果,而不是3,4或5? – Marco 2014-09-19 09:09:24

+0

我相信SSMS會使用一些唯一的行ID /數據ID來進行內部數據排序,因爲它會提取數據,這就是爲什麼它能夠爲每次運行多個select語句的行提供相同的順序。對於通過編程範例中的提供者獲取的數據,不存在這樣的內部排序。另外,訂單的數量取決於您獲取的行數,如果您有很多記錄,您會看到更高的訂單不確定性。 – 2014-09-19 13:10:46

1

如前所述,排序從不是確定性的,但可以在SQL查詢或Linq查詢中嘗試插入orderby子句,這是使其成爲確定性的唯一方法。

事實上,讓我們看一下數據庫中的更深層次的原因。數據庫將通過I/O從磁盤獲取所有數據。數據存儲在內部SQL服務器結構中,如頁面,擴展盤區(segment)(這些是Oracle數據塊,我希望sql server有類似的東西)。現在,當查詢被觸發時,數據庫會知道所有不同的位置來獲取數據,但這不是一個串行操作,而是一種並行獲取,其中不同的數據集合並在一起以提供用戶視圖。現在,正如我們所知,在線程的情況下,決不會確定誰先先返回,誰先返回,這完全是OS線程的調度,希望能進一步澄清。

OrderBy子句將對提取的數據按特定順序進行處理,因此總是會產生確定性結果。

相關問題