c#通过表达式树优雅的实现分组取TopN笔记
需要引入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笔记的更多相关文章
- spark 分组取topn
java /** *分组取topn,有序数列去除一些项后,仍然有序,所以应当先排序后分组 *@author Tele * */ public class TopDemo2 { private stat ...
- 用C#表达式树优雅的计算24点
思路:一共4个数字,共需要3个运算符,可以构造一个二叉树,没有子节点的节点的为值,有叶子节点的为运算符 例如数字{1, 2, 3, 4},其中一种解的二叉树形式如下所示: 因此可以遍历所有二叉树可能的 ...
- mysql分组取topn
本文来自 http://www.jb51.net/article/31590.htm 有些语句sql top n 是sqlserver语法 --按某一字段分组取最大(小)值所在行的数据 代码如下: ...
- 分组取topN
假设有这样一个文件,文件内容如下 class1 class2 class1 class1 class2 class2 class1 class2 class1 class2 要求按照班级分组取出每个班 ...
- SQL Server 分组取 Top 笔记(row_number + over 实现)
先看SQL语句(注意:这是在SQL Server 2005+ [包括2005] 的版本才支持的哦,o(∩_∩)o 哈哈~) SELECT col1,col2,col3 FROM table1 AS a ...
- C#学习笔记(九):LINQ和表达式树
LINQ LINQ:语言集成查询(Language Integrated Query)是一组用于c#和Visual Basic语言的扩展.它允许编写C#或者Visual Basic代码以查询数据库相同 ...
- Spark 两种方法计算分组取Top N
Spark 分组取Top N运算 大数据处理中,对数据分组后,取TopN是非常常见的运算. 下面我们以一个例子来展示spark如何进行分组取Top的运算. 1.RDD方法分组取TopN from py ...
- C# Lambda表达式详解,及Lambda表达式树的创建
最近由于项目需要,刚刚学完了Action委托和Func<T>委托,发现学完了委托就必须学习lambda表达式,委托和Lambda表达式联合起来,才能充分的体现委托的便利.才能使代码更加简介 ...
- LinQ实战学习笔记(三) 序列,查询操作符,查询表达式,表达式树
序列 延迟查询执行 查询操作符 查询表达式 表达式树 (一) 序列 先上一段代码, 这段代码使用扩展方法实现下面的要求: 取进程列表,进行过滤(取大于10M的进程) 列表进行排序(按内存占用) 只保留 ...
- c# 表达式树(一)
前言 打算整理c# 代码简化史系列,所以相关的整理一下,简单的引出一下概念. 什么是表达式树呢? 表达式树以树形数据结构表示代码,其中每一个节点都是一种表达式,比如方法调用和 x < y 这样的 ...
随机推荐
- 华山论“件”:Kafka、RabbitMQ、RocketMQ技能大比拼
摘要:主流的消息中间件包含Kafka.RabbitMQ和RocketMQ,本期云图说为您介绍它们之前的差异. 本文分享自华为云社区<第234期 华山论"件"-Kafka.Ra ...
- Hadoop中mapreduce作业日志是如何生成的
摘要:本篇博客介绍了hadoop中mapreduce类型的作业日志是如何生成的.主要介绍日志生成的几个关键过程,不涉及过多细节性的内容. 本文分享自华为云社区<hadoop中mapreduce作 ...
- 硬核化解ISV四大痛点,华为云智联生活行业加速器助力伙伴实现商业成功
摘要:场景化展现合作伙伴.客户的案例,以期针对性的解决行业痛点,帮助伙伴共筑全场景智联生活. 本文分享自华为云社区<硬核化解ISV四大痛点,华为云智联生活行业加速器助力伙伴实现商业成功>, ...
- Solon Aop 特色开发(5)切面与环绕拦截
Solon,更小.更快.更自由!本系列专门介绍Solon Aop方面的特色: <Solon Aop 特色开发(1)注入或手动获取配置> <Solon Aop 特色开发(2)注入或手动 ...
- Python 获取控制台输入的值
获取控制台输入参数 if __name__ == '__main__': while 1: question = input('用户:') answer = "你的问题是:" + ...
- 使用root ssh登录ubuntu22.4配置
前言 在安装k8s集群时,需要使用root用户ssh登录远程服务器进行安装操作,但是root登录是默认关闭的,因此本篇讲解如何开启配置, 当前测试版本 ubuntu22.4 安装部署 使用管理权限打开 ...
- 【JAVA基础】Session使用
Session使用 用户注册 详见: https://blog.csdn.net/maxiangyu_/article/details/124088948 BaseController package ...
- Educational Codeforces Round 110 (Rated for Div. 2) (AB签到,C题双指针,D题DP好题)
补题链接:Here 1535A. Fair Playoff 四名选手参加了季后赛.比赛按以下方案进行:第一名选手与第二名选手比赛,第三名选手与第四名选手比赛,然后两人中的获胜者进入决赛. 众所周知,在 ...
- L2-010. 排座位(种类并查集)
布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位.无论如何,总不能把两个死对头排到同一张宴会桌旁!这个艰巨任务现在就交给你,对任何一对客人,请编写程序告诉主人他们是否能被安排同席. 输入格式: ...
- Spark 数据倾斜及其解决方案
本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/lqMu6lfk-Ny1ZHYruEeBdA 作者简介:郑志彬,毕业于华南理工大学计算机科学与技术(双 ...