需要引入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. ServiceWorker工作机制与生命周期:资源缓存与协作通信处理

    在 <web messaging与Woker分类:漫谈postMessage跨线程跨页面通信>介绍过ServiceWorker,这里摘抄跟多的内容,补全 Service Worker 理解 ...

  2. kubeadm init port is in use

    前一次 init 时,master ip 写错了,导致init 失败,修改IP后再次执行时,报 kubeadm init 失败,port is in use Last login: Thu Oct 1 ...

  3. Java 项目工程搭建 --创建父工程

    Java 项目工程搭建 --创建父工程 Java 项目工程搭建 --创建子模块(依赖父工程) Intellij 2018 更多详细内容见尚硅谷阳哥视频,实际项目中更多的是copy,修改pom Inte ...

  4. 【Docker】基础原理

    基础原理 基础流程 Docker镜像讲解 Docker容器讲解 创建容器的两种方式 容器创建命令详解

  5. C++岗位面试真题宝典 -- 操作系统篇

    2.1 Linux中查看进程运行状态的指令.查看内存使用情况的指令.tar解压文件的参数. 参考回答 查看进程运行状态的指令:ps命令."ps -aux | grep PID",用 ...

  6. 活动回顾|阿里云 Serverless 技术实战与创新上海站回放&PPT下载

    5月27日"阿里云 Serverless 技术实战与创新"上海站圆满落幕.活动现场邀请了来自阿里云 一线技术专家,分享当前 Serverless 趋势和落地实践过程中的挑战和机遇: ...

  7. 定向减免!函数计算让 ETL 数据加工更简单

    业内较为常见的高频短时 ETL 数据加工场景,即频率高时延短,一般费用大头均在函数调用次数上,推荐方案一般为攒批处理,高额的计算成本往往令用户感到头疼,函数计算推出定向减免方案,让 ETL数据加工更简 ...

  8. element的table组件在flex布局下宽度不能自适应

    问题描述 用了flex布局,左侧固定宽度,右侧flex:1:(表格在右侧区域),且中间容器都有width:100%,当将屏幕变大,表格随着变宽,当屏幕变小时,表格不会随着屏幕变小,宽度无法自适应. 解 ...

  9. C#排序算法3:插入排序

    插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的.记录数增1的有序表. 原理: ⒈ 从第一个元素开始,该元素可以认为已经被排序 ⒉ 取出下一个元素,在已 ...

  10. DDD领域驱动设计 (C# 整理自“老张的哲学”)

    大话DDD领域驱动设计 概念 Domain Driven Design 领域驱动设计 第一个D(Domain): 领域:指围绕业务为核心而划分的实体模块. 第二个D(Driven): 驱动:这里的驱动 ...