按smalldatetime排序字段在SQL Server和C#(实体框架)中产生不同的结果

时间:2019-01-09 08:09:12

标签: c# sql-server entity-framework datetime

我有一个表,其中的字段LastChange的类型为smalldatetime。在此字段上按升序排序时,得到以下信息:

enter image description here

我已经在实体框架中创建了与此对应的实体。 LastChange字段的类型为DateTime

当我执行类似的排序操作时:

teams.OrderBy(x => x.LastChange).Select(x => x.TeamID)

我得到以下结果:

[0]: 158
[1]: 161
[2]: 159
[3]: 160
[4]: 165
[5]: 163
[6]: 166
[7]: 167
[8]: 168
[9]: 169
[10]: 170
[11]: 171
[12]: 1172
[13]: 162
[14]: 164
[15]: 172

为什么两个结果不同?是否因为多个记录的LastChange值相同?还是与smalldatetime类型有关?

3 个答案:

答案 0 :(得分:1)

两个结果都是正确的。 您期望仅通过“ LastChange”列进行排序。由于LastChange列的精确度(以分钟为单位),因此您将获得正确的结果。在您选择的示例中,SQL或C#不会打扰其他数据。 而是为LastChange列添加二阶参数或增加输入的进动。

答案 1 :(得分:1)

这是因为LastChange字段对于几行完全相同。试试这些:

SELECT *
FROM YourTable
ORDER BY LastChange, TeamID;

teams.OrderBy(x => x.LastChange).ThenBy(x => x.TeamID).Select(x => x.TeamID)

在两个地方,您将获得完全相同的结果。如果不指定第二个字段的顺序,则SQL将显示随机结果(对于未指定的字段),通常是相同的,但可以完全不同。

答案 2 :(得分:0)

  

是因为多个记录的LastChange值相同吗?

是的。 c#或数据库都不会在对LastChange进行排序后尝试进一步对结果进行排序,因此对于LastChange相同的任何值,该集合中的行可以按任何顺序排列,因此将没有一致性-一天,它们将这样排序,然后,如果数据库重新组织了表中的数据,它们将具有不同的顺序。 C#可能完全不同地对事物进行排序,这是其余排序算法如何工作的副作用。不能保证db和c#总是以相同的方式排序。他们都会放弃排序,直到在LastChange上可以得到为止

如果您始终希望数据按特定顺序排列,则必须对其进行精确排序。如果数据本身没有可排序的内容,那么必须编写自己的排序系统或提供其他数据

例如,如果我们始终希望从仅包含名称的数据库表中获取此数据:

Tim
James
John

它不是字母,反向字母,秒字符,也不是按长度排序,依此类推。关于这些数据,我们无法根据数据本身进行排序,因此我们必须:

ORDER BY 
  CASE personname
    WHEN 'Tim' THEN 0
    WHEN 'James' THEN 1
    WHEN 'John' THEN 2
  END

在这里,我们已经将字面上的数据转换为可排序的内容

TLDR;如果您始终希望以某种方式对数据进行排序,则必须针对每个行。您排序依据的列组合必须唯一。一旦按一组不唯一的列进行排序,相同的数据可能会以任何不一致的随机顺序出现

  

这与smalldatetime类型有关吗?

否,它会影响所有要排序的数据集,其中不止一行具有相同的值,并且没有什么进一步帮助排序算法选择应将相同行中的哪一行排在首位