【问题标题】:Dynamic Linq to Entities Orderby with Pagination [duplicate]带分页的动态Linq到实体Orderby [重复]
【发布时间】:2017-04-25 10:14:43
【问题描述】:

我有一个包含超过 80 万条记录的 SQL 表,这些记录需要在 25 个结果的页面中显示在 Web 上。我需要能够从表中搜索和排序这些结果,但由于表太大,我无法在过滤/排序之前将所有结果拉到 IEnumerable 中(我之前这样做过并且它有效,但现在令人难以置信初始拉动速度慢)。

我已经弄清楚了搜索,但排序真的把我弄乱了。我花了几个小时研究它,但在 .Skip().Take() 之前找不到任何可行的解决方案。

我需要能够做这样的事情:

string sortField = "Name"; //just for example
string sortDirection = "descending"; //also for example
List<People> = (from s in db.People
                orderby sortField sortDirection
                select s).Skip((page - 1) * pageSize).Take(pageSize).ToList();

People 中的可排序列可以是 DateTime、int 或字符串,所以我尝试做类似的事情

orderby (
    currentSort == "Name" ? s.Name : 
    currentSort = "SignUpDate" ? s.SignupDate : s.Id
)

徒劳无功,因为程序抱怨混合类型。

有什么可以做的吗?提前感谢任何帮助或线索!

【问题讨论】:

  • 您是按单列排序吗?
  • 是的,一次只有一列
  • 您订购的列是否有索引?

标签: c# linq model-view-controller linq-to-entities


【解决方案1】:

您可以使用以下自定义扩展方法,该方法使用System.Linq.Expressions.Expression 类动态构建OrderBy(Descending) 调用(类似于How to use a string to create a EF order by expression?):

public static partial class QueryableExtensions
{
    public static IOrderedQueryable<T> OrderByMember<T>(this IQueryable<T> source, string memberPath, bool descending)
    {
        var parameter = Expression.Parameter(typeof(T), "item");
        var member = memberPath.Split('.')
            .Aggregate((Expression)parameter, Expression.PropertyOrField);
        var keySelector = Expression.Lambda(member, parameter);
        var methodCall = Expression.Call(
            typeof(Queryable), descending ? "OrderByDescending" : "OrderBy", 
            new[] { parameter.Type, member.Type },
            source.Expression, Expression.Quote(keySelector));
        return (IOrderedQueryable<T>)source.Provider.CreateQuery(methodCall);
    }
}

像这样:

var people = db.People
    .OrderByMember(sortField, sortDirection == "descending")
    .Skip((page - 1) * pageSize).Take(pageSize)
    .ToList();

【讨论】:

  • 当您发现某个问题重复时,您应该投票关闭它,而不仅仅是复制粘贴您对重复问题的答案。
  • @Servy 同意。我通常这样做,但在这里决定它是一种变体,而另一个答案并不直接适用。但你是对的,我应该搜索其他重复项。
  • @Servy 我确实环顾了几个小时,尝试了我能找到的所有解决方案,但没有运气。伊万,非常感谢你!这非常有效!
  • @Zach 不客气,很高兴它有帮助:)
  • @CharlesOkwuagwu 动态的Where 大不相同,主要是签名(参数)和支持的操作(例如nameoperatorvalue 等)。 Dynamic LINQ 为这两个问题提供了一个完整的解决方案,但是如果您想要一个定制的方法来满足您的需求,您可以发布一个问题,我很乐意查看它。干杯。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-02
  • 2017-09-15
相关资源
最近更新 更多