需要引入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);
}
}

c#通过表达式树优雅的实现分组取TopN笔记的更多相关文章

  1. spark 分组取topn

    java /** *分组取topn,有序数列去除一些项后,仍然有序,所以应当先排序后分组 *@author Tele * */ public class TopDemo2 { private stat ...

  2. 用C#表达式树优雅的计算24点

    思路:一共4个数字,共需要3个运算符,可以构造一个二叉树,没有子节点的节点的为值,有叶子节点的为运算符 例如数字{1, 2, 3, 4},其中一种解的二叉树形式如下所示: 因此可以遍历所有二叉树可能的 ...

  3. mysql分组取topn

    本文来自  http://www.jb51.net/article/31590.htm 有些语句sql top n 是sqlserver语法 --按某一字段分组取最大(小)值所在行的数据 代码如下: ...

  4. 分组取topN

    假设有这样一个文件,文件内容如下 class1 class2 class1 class1 class2 class2 class1 class2 class1 class2 要求按照班级分组取出每个班 ...

  5. SQL Server 分组取 Top 笔记(row_number + over 实现)

    先看SQL语句(注意:这是在SQL Server 2005+ [包括2005] 的版本才支持的哦,o(∩_∩)o 哈哈~) SELECT col1,col2,col3 FROM table1 AS a ...

  6. C#学习笔记(九):LINQ和表达式树

    LINQ LINQ:语言集成查询(Language Integrated Query)是一组用于c#和Visual Basic语言的扩展.它允许编写C#或者Visual Basic代码以查询数据库相同 ...

  7. Spark 两种方法计算分组取Top N

    Spark 分组取Top N运算 大数据处理中,对数据分组后,取TopN是非常常见的运算. 下面我们以一个例子来展示spark如何进行分组取Top的运算. 1.RDD方法分组取TopN from py ...

  8. C# Lambda表达式详解,及Lambda表达式树的创建

    最近由于项目需要,刚刚学完了Action委托和Func<T>委托,发现学完了委托就必须学习lambda表达式,委托和Lambda表达式联合起来,才能充分的体现委托的便利.才能使代码更加简介 ...

  9. LinQ实战学习笔记(三) 序列,查询操作符,查询表达式,表达式树

    序列 延迟查询执行 查询操作符 查询表达式 表达式树 (一) 序列 先上一段代码, 这段代码使用扩展方法实现下面的要求: 取进程列表,进行过滤(取大于10M的进程) 列表进行排序(按内存占用) 只保留 ...

  10. c# 表达式树(一)

    前言 打算整理c# 代码简化史系列,所以相关的整理一下,简单的引出一下概念. 什么是表达式树呢? 表达式树以树形数据结构表示代码,其中每一个节点都是一种表达式,比如方法调用和 x < y 这样的 ...

随机推荐

  1. SpringBoot Jar 包太大 瘦身 【初试】

    SpringBoot Jar 包太大 瘦身,建议使用时,参考: SpringBoot Jar 包太大 瘦身 [终极版] 29M, 排除少量JAR包方式 打包,排除指定jar 包 <build&g ...

  2. LSP 网络劫持(Layered Service Provider Hijacking)

    LSP 简介: 分层服务提供商(Layered Service Provider,LSP)是一种可以扩展Winsock作为应用程序的 Windows 的网络套接字工具的机制.Winsock LSP 可 ...

  3. html5 video视频,本地环境好的,线上环境,不能播放

    本地环境ok,发布到线上不能播放.之前看这个视频,把video放在public文件夹下的. 后来经过排查,video放public文件夹下,导致的.应该放assets里. 后来,和同事讨论,线上服务器 ...

  4. [工程开发]当我们写一个tcp服务端的时候,我们在写什么?(一)

    当我们写一个tcp服务器和客户端的时候,我们在写什么?(一) 本篇只聊服务端. 最近想搞一个服务器的协议,然后捏,简单搓个tcp服务器协议看看效果,主要是最近实在是没事干,闲得没事搓个服务器看看,当然 ...

  5. C# 排序算法2:选择排序

    选择排序法 ,是在要排序的一组数中,选出最小(或最大)的一个数与第一个位置的数交换:在剩下的数当中找最小的与第二个位置的数交换,即顺序放在已排好序的数列的最后,如此循环,直到全部数据元素排完为止. 原 ...

  6. 简单的winform学生管理系统Demo

    界面效果 练习重点 1. 关系表的创建 2. 增删改查的操作,及sqlhelper的封装 3. 跨页面数据传递,编辑页数据提交后数据局步刷新到列表数据 项目源码 FrmStuddentList pub ...

  7. 信息收集-CDN绕过

    什么是CDN加速? CDN 的全称是 Content Delivery Network,即内容分发网络.CDN 是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器, 通过中心平台的负载 ...

  8. java基础(16)--super与this

    一.this简介 1.this.  this() 2.静态方法无法使用 3.不省略的情况:区分局部变量与实例变量,比如set方法中用到   二.super简介 1.只能出现在实例方法或构造方法中 2. ...

  9. ThreadLocal应用及理解

    转载请注明出处: 1. 先展示threadLocal的一个简单封装,该封装用来在不同的请求线程中解析用户参数.在请求经过过滤器时, 对用户的信息进行设置入 ThreadLocalContext 中,可 ...

  10. MYSQL varchar和nvarchar一些学习

    MYSQL varchar和nvarchar一些学习 背景 先试用 utfmb3的格式进行一下简单验证 注意脚本都是一样的. create database zhaobsh ; use zhaobsh ...