需要引入nuget包来实现ef.functions调用row_number
Thinktecture.EntityFrameworkCore.SqlServer
调用方式:
//顺排 context.Table.GroupBySortTop(1, x => x.partitionProptery, x => x.orderByProperty).ToList() //倒排 context.Table.GroupBySortTopDescending(1, x => x.partitionProptery, x => x.orderByProperty).ToList()
核心代码
public class GroupBySorting<T> { public T Data { get; set; } public long Rowid { get; set; } } public static class Extension { static string OrderBy = nameof(RelationalDbFunctionsExtensions.OrderBy); static string OrderByDescending = nameof(RelationalDbFunctionsExtensions.OrderByDescending); static MethodInfo RowNumber = typeof(RelationalDbFunctionsExtensions).GetMethods().FirstOrDefault(x => x.IsGenericMethod && x.Name == nameof(RelationalDbFunctionsExtensions.RowNumber)); static Dictionary<string, MethodInfo> OrderMethods = new List<(string, MethodInfo)>() { new (OrderBy, typeof(RelationalDbFunctionsExtensions).GetMethod(OrderBy)), new (OrderByDescending, typeof(RelationalDbFunctionsExtensions).GetMethod(OrderByDescending)) }.ToDictionary(x => x.Item1, x => x.Item2); static IQueryable<T> GroupBySortTop<T, T1, T2>(this IQueryable<T> source, int limit, Expression<Func<T, T1>> partitionByExpression, Expression<Func<T, T2>> orderByExpression, string orderBy) { var prm = Expression.Parameter(typeof(T)); var constFunc = Expression.Constant(EF.Functions); var orderFunc = Expression.Call(null, OrderMethods[orderBy].MakeGenericMethod(typeof(int)), constFunc, Expression.Property(prm, (orderByExpression.Body as MemberExpression).Member.Name)); var expressions = Expression.Call(null, RowNumber.MakeGenericMethod(typeof(T1)), constFunc, Expression.Property(prm, (partitionByExpression.Body as MemberExpression).Member.Name), orderFunc); var targetType = typeof(GroupBySorting<T>); var memberBindings = new List<MemberBinding>(); memberBindings.Add(Expression.Bind(targetType.GetProperty(nameof(GroupBySorting<T>.Data)), prm)); memberBindings.Add(Expression.Bind(targetType.GetProperty(nameof(GroupBySorting<T>.Rowid)), expressions)); var initmember = Expression.MemberInit(Expression.New(typeof(GroupBySorting<T>)), memberBindings); var lambda = Expression.Lambda<Func<T, GroupBySorting<T>>>(initmember, prm); return source.Select(lambda).AsSubQuery().Where(x => x.Rowid <= limit).Select(x => x.Data); } public static IQueryable<T> GroupBySortTop<T, T1, T2>(this IQueryable<T> source, int limit, Expression<Func<T, T1>> partitionByExpression, Expression<Func<T, T2>> orderByExpression) { return GroupBySortTop(source, limit, partitionByExpression, orderByExpression, OrderBy); } public static IQueryable<T> GroupBySortTopDescending<T, T1, T2>(this IQueryable<T> source, int limit, Expression<Func<T, T1>> partitionByExpression, Expression<Func<T, T2>> orderByExpression) { return GroupBySortTop(source, limit, partitionByExpression, orderByExpression, OrderByDescending); } }标签:source,c#,TopN,static,typeof,var,分组,Expression,RelationalDbFunctionsExtensions From: https://www.cnblogs.com/gmmy/p/16624477.html