【问题标题】:Weird LINQ OrderBy Behavior奇怪的 LINQ OrderBy 行为
【发布时间】:2015-10-01 20:47:25
【问题描述】:

我正在尝试使用 LINQ 和 Entity Framework 获得一个排序列表,但我得到了一些非常奇怪的结果。我的代码如下所示:

// My class that corresponds to a database table
class MyClass
{
   public string FirstField { get; set; }
   public string SecondField { get; set; }
   public string ThirdField { get; set; }
}

// My Entity Framework code
List<MyClass> firstList = (from p in context.myObjects select p).OrderBy(p => p.FirstField).ToList();
List<MyClass> secondList = firstList.OrderBy(p => p.FirstField).ToList();

当我查看结果时,secondList 排序正确,但 firstList 排序不正确。在大多数情况下,它的排序是正确的,但有些元素是乱序的。例如,firstList 看起来像这样:

AAA
BBB
CCC
DDD
NNN   <--- wrong order
EEE
FFF
GGG
PPP   <--- wrong order
HHH
III

但是,secondList 的排序完全正确。

我检查了 LINQ 正在创建的查询,该查询具有正确的 ORDER BY。我在 SQL Management Studio 中运行了相同的查询,结果排序正确(与 secondList 的顺序相同,但不是 firstList)。我尝试在我的 LINQ 查询中使用 orderby,而不是使用 OrderBy(),结果以同样的方式不正确。

我不明白这里发生了什么。 firstList不应该排序,firstList和secondList不应该都一样吗?

我正在使用 Fluent API 将我的对象映射到表和属性到字段,如果这有什么不同的话。

【问题讨论】:

  • 我看不出你所拥有的有什么问题。 firstList 应该被排序,并且应该与 secondList 完全相同。唯一的区别是第一个将按 db 排序,而第二个将按 .NET 排序。您的示例数据实际上是排序的,还是数据库上的联盟设置不是您期望的其他东西? (排序 u 和 u 与变音符号相同等)?
  • 这不是我的确切生产代码,但排序不应该是排序的问题。真实数据有大约 1000 个值,其中有大约 50 个不同的值。发生的事情是排序顺序类似于 A,A,A,A,B,B,B,B,A,B,B,B,C,C,A,C,C,D,...。
  • 这很难重现,所以尝试不同的选项。如果您像 firstList = context.myObjects.OrderBy(p =&gt; p.FirstField).ToList(); 这样创建第一个列表,您还会看到未排序的列表吗?
  • 可能是索引损坏?

标签: entity-framework linq


【解决方案1】:

我明白问题所在了。谢谢大家的建议;它让我找对了地方。问题是该表有一个由 FirstField、SecondField 和 ThirdField 组成的复合键。当我使用 Fluent API 配置 Context 时,我从 Context 的其他地方复制了一些代码,我不小心将表的主键设置为 FirstField。这导致实体框架将 SecondField 和 ThirdField 的相同值分配给 FirstField 的每个不同值。例如,如果数据库中的行是 {A, BB, CCC}, {A, EE, FFF}, {A, HH, III},Entity Framework 给我 {A, BB, CCC}, {A, BB, CCC}, {A, BB, CCC}。我更正了我的 HasKey(),现在一切正常。

【讨论】:

    【解决方案2】:

    在您的示例中,firstList 正在从数据库中进行排序, secondList 正在从内存中的对象中进行排序。 (两个列表都应该给你相同的结果,但是他们的排序与数据库不同,另一个在内存中排序,所以可能有一个错误的索引是一个原因)

    如果您尝试以下代码,我们会在内存中对 firstList 和 secondList 进行排序,并且它们将得到相同的结果

    我在 firstList 语法中添加了第二个 .ToList(),这将导致数据被检索然后排序。而是在你的 sql 代码中构建一个 orderby 子句。

    List<MyClass> firstList = (from p in context.myObjects select p).ToList().OrderBy (p=>p.FirstField).ToList();
    
    
    List<MyClass> secondList = firstList.OrderBy(p => p.FirstField).ToList();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多