在 LINQ Where(x => f(x) > y) 和 OrderBy(f) 与 SQL 编译中使用相同的委托

using same delegate in LINQ Where(x => f(x) > y) and OrderBy(f) with SQL compilation

我正在尝试为 EFCore 编写一个相对简单但通用的分页函数,但我无法找到正确的函数类型来确保我的排序键选择器被转换为 SQL WhereOrderBy 子句。

    public List<TItem> GetPage<TItem>(IQueryable<TItem> items, TFunc keyExtractor, int? itemsAfter = default)
    {
        if (itemsAfter != default)
        {
            items = items.Where(item => keyExtractor(item) > itemsAfter);
        }

        var materialized = items.OrderBy(keyExtractor).Take(pageSize).ToList();

        // ... stuff to trim page size ...
    }

是否有更好的方法将其中一种转换为另一种,以便翻译查询?或者有没有我可以接受的第三种类型可以很容易地制成这两种类型?我的 keyExtractor 参数都比较简单,例如item => item.id。由于我无法控制的原因,我目前只能使用 EFCore 2.1

对于Expression<Func<TItem, int>>,您需要自己构建大于表达式。沿着这条线:

public List<TItem> GetPage<TItem>(IQueryable<TItem> items, Expression<Func<TItem, int>> keyExtractor, int? itemsAfter = default)
{
    if (itemsAfter != default)
    {
        var greaterThan = Expression.GreaterThan(keyExtractor.Body, Expression.Constant(itemsAfter));
        var filter = Expression.Lambda<Func<TItem, bool>>(greaterThan, keyExtractor.Parameters);
        items = items.Where(filter);
    }
     var materialized = items.OrderBy(keyExtractor).Take(pageSize).ToList();
     // ... stuff to trim page size ...

}