【问题标题】:Convert IQueryable to IOrderedQueryable将 IQueryable 转换为 IOrderedQueryable
【发布时间】:2013-10-22 15:38:41
【问题描述】:

我有 2 个表:Items 和 ItemMetrics。 Items 包含我的项目,ItemMetrics 包含有关这些项目的统计信息。

我正在尝试按相应的统计权重对项目列表进行排序。 我使用子查询让它工作,但我认为它有点效率低下,可以优化......

items.OrderBy(item => (from metric in Context.ItemMetrics where item.ItemId == metric.ItemId select metric.Weight).FirstOrDefault());

...所以我正在尝试使用连接来完成同样的事情...

from item in items join metric in ItemMetrics on item.ItemId equals metric.ItemId orderby metric.Weight select item;

这在 LINQPad 中运行良好。我需要为补充方法返回一个 IOrderedQueryable 以使用 Skip 和 Take 进行一些分页,但编译器告诉我这个查询的结果是一个 IQueryable。

我能想到的明确暗示 IOrderedQueryable 的唯一方法是将查询包装在

OrderBy(x => 0)

有没有更好的办法?

【问题讨论】:

    标签: c# linq join


    【解决方案1】:

    问题是IOrderedQueryable 需要能够应用二级排序 - 当您将项目/指标对投影到一个项目时,您已经失去了一级排序。

    一种方法是将投影推迟到以后:

    var ordered = items.Join(ItemMetrics,
                             item => item.ItemId,
                             metric => metric.ItemId,
                             (item, metric) => new { item, metric })
                       .OrderBy(pair => pair.Metric.Weight);
    var paged = ApplyPaging(ordered, pageConfiguration); // Whatever
    var query = paged.Select(pair => pair.Item);
    

    这是假设 ApplyPaging(或任何您使用的)返回 IQueryableIOrderedQueryable

    【讨论】:

    • 谢谢。一个问题:将结果转换为 IOrderedQueryable 是否安全?我之前没有这样做,因为我之前有过 Skip and Take 投诉,但在发布后我只是将其添加为猜测并且它有效。
    • @DavidJamesBall:选哪个结果?来自您原始查询的那个?老实说,我很惊讶它的工作原理......我个人不会依赖它,因为目前它听起来像是一个方便的实现细节。如果我的方法有效,我会改用它。
    猜你喜欢
    • 1970-01-01
    • 2019-12-19
    • 2010-12-16
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多