繁体   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