我正在尝试使用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将我的对象映射到表格和属性到字段,如果这有任何区别。
答案 0 :(得分:1)
我明白了问题所在。谢谢大家的建议;它让我看着正确的地方。问题是该表有一个由FirstField,SecondField和ThirdField组成的复合键。当我使用Fluent API配置我的Context时,我正在从我的Context中的其他地方复制一些代码,并且我不小心只将表的主键设置为FirstField。这导致实体框架将SecondField和ThirdField的相同值分配给FirstField的每个不同值。例如,如果数据库中的行是{A,BB,CCC},{A,EE,FFF},{A,HH,III},实体框架给了我{A,BB,CCC},{A, BB,CCC},{A,BB,CCC}。我纠正了我的HasKey(),现在一切正常。
答案 1 :(得分:0)
在您的示例中,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();