【问题标题】:How to order a list<object> by its current order so it will be accepted by PagedList?如何按当前顺序对 list<object> 进行排序,以便被 PagedList 接受?
【发布时间】:2015-11-12 23:19:18
【问题描述】:

问题:“方法 'Skip' 仅支持 LINQ to Entities 中的排序输入。方法 'OrderBy' 必须在方法 'Skip' 之前调用。”

list2 = list1.Where(a).OrderBy(x => x.Something).Union(list1.Where(x).OrderBy(x => x.SomethingDifferent));
return list2.ToPagedList(...);

我认为发生这种情况是因为它需要在“Union”之后有一个新的“OrderBy”。有没有什么办法可以把它变成一个 OrderedList,同时保持来自 Union 的当前订单?

有没有办法添加另一个 OrderBy,它实际上不会改变订单,例如:

list2 = list1.Where(a).OrderBy(x => x.Something).Union(list1.Where(x).OrderBy(x => x.SomethingDifferent)).OrderBy(x => x.NothingThatWillAffectTheOrder);

编辑

为了更清楚地说明这一点,我将用一个实际的例子来解释。

假设用户在电影数据库中搜索,并且您想在包含搜索字符串的演员姓名之前显示包含搜索字符串的标题。

list = movies.Where(x => x.Title.Contain...).Union(movies.Where(x => x.Actors.Contain..)

PagedList 不会接受这个,因为它没有排序,但是排序这个列表会违背联盟的目的。在保持当前顺序的同时,是否有一种“变通方法”来使其成为有序列表?

【问题讨论】:

  • 我删除了我之前的答案,因为我没有完全理解你的问题。在使用来自github.com/TroyGoode/PagedList 的 PagedList 时,我没有遇到关于“跳过”方法的任何问题。你用的是那个吗?
  • 是的,这就是我正在使用的。问题是因为两个 OrderBys 发生在 Union 之前,所以 PagedList 不会接受它。我将编辑我的问题以提供更好的示例。
  • 我不明白您为什么会收到该错误,但我添加了一个具有完整功能实现的新答案。

标签: c# linq list pagedlist


【解决方案1】:

我不确定您为什么会收到您的错误。但是,我能够根据您提供的信息编写一个可以正常工作的程序。看看以下内容。希望它可以帮助您准确地发现您正在做的不同之处。 请注意,我的 ToString() 实现使用了 C# 6 中的一项新功能。如果您使用的是旧版本的 C#,则必须稍微修改该行。

using PagedList;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    class Actor
    {
        public string Title { get; set; }
        public List<string> Actors { get; set; }
        public override string ToString()
        {
            return $"{Title} featuring {string.Join(", ", Actors)}";
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            List<Actor> movies = new List<Actor>()
            {
                new Actor() { Title = "Star Wars", Actors = new List<string>() {  "Mark Hamill", "Harrison Ford" } },
                new Actor() { Title = "Indiana Jones and The Raiders of the Lost Ark", Actors = new List<string>() {  "Karen Allen", "Harrison Ford" } },
                new Actor() { Title = "Indiana Jones and The Temple of Doom", Actors = new List<string>() {  "Kate Kapshaw", "Harrison Ford" } },
                new Actor() { Title = "Indiana Jones and The Kingdom of the Crystal Skull", Actors = new List<string>() {  "Cate Blanchett", "Harrison Ford" } },
                new Actor() { Title = "Jessica Jones", Actors = new List<string>() {  "Krysten Riter", "David Tennant" } },
                new Actor() { Title = "The Wizard of Oz", Actors = new List<string>() {  "Judy Garland" } },
            };

            var list = movies.Where(x => x.Title.Contains("Jones")).Union(movies.Where(x => x.Actors.Contains("Harrison")));

            var pagedList = list.ToPagedList(1, 2);

            foreach (var movie in pagedList)
            {
                Console.WriteLine(movie);
            }
        }
    }
}

【讨论】:

    【解决方案2】:

    有一个选择重载可以让你包含序数,所以也许你可以这样做:

    list1.Where(a).OrderBy(x => x.Something)
        .Union(list1.Where(x).OrderBy(x => x.SomethingDifferent))
        .Select((item,idx) => new { item, idx })
        .OrderBy(x => x.idx);
    

    不幸的是,这意味着您选择的类型与以前不同。但根据您实际使用它的方式,也许您可​​以使用以下内容将其展平:

     .Select((item,idx) => new { item.Title, item.SomeOtherProperty, idx })
    

    如果有什么消耗它可以躲避类型,可能是可行的

    【讨论】:

    • 有趣的是,这个问题是 22 小时前的,我们都在几秒钟内回答了对方。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 2021-06-18
    • 1970-01-01
    • 2018-10-28
    相关资源
    最近更新 更多