【问题标题】:Implementation of List<T> is losing the ordering on the original queryList<T> 的实现正在丢失原始查询的排序
【发布时间】:2014-03-09 05:52:18
【问题描述】:

使用实体框架我有一个IQueryable 用于数据库对象MeetingeDbContext

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);
        }
    }

【问题讨论】:

  • 您是否尝试通过调用 .ToList() 来枚举结果?你为什么要尝试通过代理键订购任何东西?
  • 如何申请OrderBy? temp 是什么?生成了哪些查询?
  • 是否有索引应用于Meetings 表? select 中的另一个 set 字段可能意味着 DB 使用的另一个索引,这可能意味着另一个 order。
  • 什么是 sortedMeetings?
  • 添加了更多关于什么是 sortedMeetings 的信息。除了主键 MeetingID 之外,Meetings 表没有索引。

标签: asp.net linq entity-framework linq-to-entities


【解决方案1】:

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

但同时显示sortedMeetingsOrderBy 以进行完整分析。

编辑:

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

【讨论】:

  • 我怀疑你是对的@saamorim,但这并不能阻止这让我感到困惑。我在很多地方都使用了类似的逻辑,这是唯一一个即使经过彻底测试,订单似乎也会丢失的地方。无论如何,我已经更详细地更新了我原来的问题,并感谢您的想法。
【解决方案2】:

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

+1 给@saamorim,因为他扮演了一双新鲜的眼睛,并把我指向context.Database.Log,这是我不知道的。

【讨论】:

    猜你喜欢
    • 2016-02-26
    • 1970-01-01
    • 2023-03-28
    • 2015-08-13
    • 1970-01-01
    • 2011-10-09
    • 1970-01-01
    • 2017-09-27
    • 1970-01-01
    相关资源
    最近更新 更多