List 的实现<T>正在失去原始查询的顺序



使用实体框架,我有一个数据库对象Meeting IQueryableeDbContext

IQueryable<Meeting> meetings = e.Meetings
    .Include(m => m.MeetingStage)
    .Include(m => m.MeetingType)

此查询已应用OrderBy

然后,我想从此查询中选择一个新的对象MeetingSearchResult。但是,我发现在某些情况下,顺序正在更改,因为这些测试表明

var temp2 = sortedMeetings.Select(m => m.MeetingID);
System.Diagnostics.Debug.WriteLine(string.Join(" / ", temp2.ToList().ToArray()));
var temp4 = sortedMeetings.Select(m => new MeetingSearchResult()
{
       MeetingID = m.MeetingID,
       CompanyName = m.CompanyName
});
System.Diagnostics.Debug.WriteLine(string.Join(" / ", temp4.ToList().Select(m => m.MeetingID).ToArray()));
var temp8 = sortedMeetings.Select(m => new MeetingSearchResult()
{
      MeetingID = m.MeetingID,
      CompanyName = m.CompanyName,
      MeetingDate = m.MeetingDate,
      MeetingStage = m.MeetingStage.Description
});
System.Diagnostics.Debug.WriteLine(string.Join(" / ", temp8.ToList().Select(m => m.MeetingID).ToArray()));

此处调试器的输出为:

2493 / 4228 / 7029 / 8254 / 9375 / 10563 / 11716 / 10500
2493 / 4228 / 7029 / 8254 / 9375 / 10563 / 11716 / 10500
2493 / 4228 / 7029 / 8254 / 9375 / 10500 / 10563 / 11716

temp8 中对象的顺序已更改。谁能解释一下?

更多信息

人们询问了有关sortedMeetings的更多信息。

var sortedMeetings = meetings.DoMeetingSort(sort, ascending);

我的扩展DoMeetingSort如下。我已经删除了此处不适用的开关情况:

    public static IQueryable<Meeting> DoMeetingSort(this IQueryable<Meeting> query, Constants.MeetingSortColumn column, bool ascending)
    {
        switch (column)
        {
            case Constants.MeetingSortColumn.MeetingType:
                return ascending
                    ? query.OrderBy(m => m.MeetingType.Description).ThenBy(m => m.MeetingDate).ThenBy(m => m.CompanyName)
                    : query.OrderByDescending(m => m.MeetingType.Description).ThenByDescending(m => m.MeetingDate).ThenByDescending(m => m.CompanyName);
        }
    }

发生这种情况的原因有很多,但从您的样本来看,最有可能是由于底层数据库决定了这一点。我假设您的sortedMeetings仍然是IQueryable,因此查询仍在构建中。当您包含其他列并调用ToList()数据库引擎正在执行不同的查询时,它可能会决定使用另一个索引,或者只是查询的另一个路径。如果您使用的是 Sql Server,请分析您的查询并查看执行计划,但使用您想要的顺序,这是您唯一的保证。

但向sortedMeetings提供OrderBy以进行完整分析。

编辑:

此外,似乎起源IQueryable并不相同:temp2temp派生出 drom sortedMeetingstemp4temp8。此外,如果使用的是 EF6,请使用 context.Database.Log 转储查询,否则使用数据库探查器。在此处发布数据库查询,我们将帮助您进行分析。

我找到了答案。我返回的MeetingSearchResult对象没有表示要排序的列的属性,因此该列未包含在数据库查询中。我猜很明显,但让我困惑了很长时间。还解释了为什么对其他列进行排序可以正常工作。

+1 到 @saamorim 充当一双新鲜的眼睛并指向我context.Database.Log

我不知道的。

相关内容

最新更新