簡體   English   中英

檢索數據,奇怪的行為

[英]Retrieve data, strange behaviour

我使用EF 6從SQL Server檢索一些數據。 我過去遇到過這個問題,但我沒有問過任何人。

對於以下代碼,只需關注選擇。

讓我們說在數據庫中我有2行:

1 2 3 4  5 
6 7 8 9 10

我的代碼:

 var results = db.Table.Where(o => o.Version == 1)
                       .Select(o => new List<double?>{ o.M01, o.M02, o.M03, o.M04, o.M05});

 return results.ToList();

上面的代碼將返回列表列表,其中包含以下內容:

previousDemand[0] = 1 2 3 4 5
previousDemand[1] = 10 9 8 7 6

第二個清單是相反的。

如果我有更多的行,它會發生相同的事情:首先確定,第二個反轉,第三個確定,第四個反轉,依此類推。

如果我將代碼更改為:

 var results = db.Table.Where(o => o.Version == 1).ToList();
 var x = results.Select(o => new List<double?>{ o.M01, o.M02, o.M03, o.M04, o.M05});

 return x.ToList();

一切都會好起來的。

如果我在EF查詢中創建列表似乎有問題。

我錯過了重要的事嗎?

更新 添加一些截圖: Sql Server

我在EF收到的是什么

TL; DR

new List<double?> { o.M01, o.M02, o.M03, o.M04, o.M05 }.OrderBy(p => p).ToList()

該消息只對您提供的示例有效,但不能解決您的問題,正如@GertArnold在評論中指出的那樣。

你可以做的不是查詢列表,而是返回一個新實體,包含你想要的列。 在實現結果后,您可以將其轉換為列表。

var results = 
   db.Entities.Where(o => o.Version == 1)
     .Select(o => new { M01 = o.M01, M02 = o.M02, M03 = o.M03, M04 = o.M04, M05 = o.M05 });

return results.Select(o => new List<double?> { o.M01, o.M02, o.M03, o.M04, o.M05 });

現在推理:

您的EF查詢生成以下(非常混亂)SQL語句:

SELECT 
    [Project6].[Id] AS [Id], 
    [Project6].[C2] AS [C1], 
    [Project6].[C1] AS [C2]
    FROM ( 
        SELECT 
            CASE 
                WHEN ([UnionAll4].[C1] = 0) THEN [Extent1].[M01] 
                WHEN ([UnionAll4].[C1] = 1) THEN [Extent1].[M02] 
                WHEN ([UnionAll4].[C1] = 2) THEN [Extent1].[M03] 
                WHEN ([UnionAll4].[C1] = 3) THEN [Extent1].[M04] 
                ELSE [Extent1].[M05] END AS [C1], 
            [Extent1].[Id] AS [Id], 
            1 AS [C2]
        FROM  [dbo].[Entities] AS [Extent1]
        CROSS JOIN  (
            SELECT 0 AS [C1]
            FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]                
            UNION ALL               
                SELECT 1 AS [C1]
                FROM  ( SELECT 1 AS X ) AS [SingleRowTable2]                
            UNION ALL               
                SELECT 2 AS [C1]
                FROM ( SELECT 1 AS X ) AS [SingleRowTable3]             
            UNION ALL               
                SELECT 3 AS [C1]
                FROM  ( SELECT 1 AS X ) AS [SingleRowTable4]                
            UNION ALL               
                SELECT 4 AS [C1]
                FROM  ( SELECT 1 AS X ) AS [SingleRowTable5]
            ) AS [UnionAll4]
            WHERE 1 = [Extent1].[Version]
    )  AS [Project6]
ORDER BY [Project6].[Id] ASC, [Project6].[C2] ASC

正如您在ORDER BY子句中看到的那樣,查詢按[Project6]。[C2]排序,這只是一個返回1的控制標志。這是因為,在注釋中指定的@marc_s,您沒有明確指定訂單結果。

如果你改為使用somenting:

var results = db.Entities.Where(o => o.Version == 1).Select(o => new List {o.M01,o.M02,o.M03,o.M04,o.M05} .OrderBy (p => p)。ToList());

...然后生成的SQL將包含正確的order子句,您將獲得exepcted結果。

var results = 
   db.Entities.Where(o => o.Version == 1)
     .Select(o => new { M01 = o.M01, M02 = o.M02, M03 = o.M03, M04 = o.M04, M05 = o.M05 });

return results.Select(o => new List<double?> { o.M01, o.M02, o.M03, o.M04, o.M05 });

...然后您不需要為生成的SQL順序而煩惱,並且可以控制在輸出列表中返回列的順序。

這是EF從源自一個數據庫記錄的值實現List<T>對象的方式中可重現的故障。 事實證明,執行的SQL語句以此意外的交替順序返回值。 這意味着EF生成的SQL查詢永遠不能保證返回特定的訂單。 但由於SQL是一種基於集合的語言,因此它永遠不會保證集合中元素的順序。 有可能生成一個正確排序元素的查詢SQL,但我認為EF從未預料到你的(不那么常見)場景,或者認為值得努力支持它。

因為它是EF源代碼的一部分,所以沒有快速的方法來解決它,你必須解決你的解決方案。 您可能想要提交錯誤報告。

根本問題IMO是錯誤的數據規范化。 如果您的表將是M記錄表的父級 - 每個表示一個雙精度值,可能帶有序列字段 - 獲取此列表列表會容易得多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM