表达式树扩展 动态生成表达式树插件 Sy.ExpressionBuilder。
CURD中,基础查询我感觉还是很烦人的一个浪费时间的工作,我经历过远古时代的GetAll(string name,int age),这种方式写服务的时候真的是心中一万个草泥马飞过,后面逐渐的变成了传一个实体GetAll([FromQuery] GetDto)似乎也能默默的忍受,然后含泪写着一堆的WhereIf,目前这种方式应该还是很多人在用的一种方式。作为新生代的农民工,我们是自然不能忍受一直这样,于是就有Sy.ExpressionBuilder(大家可以去nuget下载试用)这个查询插件,似乎我们有了更好的选择。
为了方便后面的介绍,先让我们有几个实体,用户表,角色表,系统表,我们约定一个用户只有一种角色,但是可以存在多个系统中。
/// <summary>
/// 用户表
/// </summary>
public class Manager
{
/// <summary>
/// 编号
/// </summary>
public string Id { get; set; } /// <summary>
/// 名称
/// </summary>
public string Name { get; set; } /// <summary>
/// 手机
/// </summary>
public string Tel { get; set; } /// <summary>
/// 角色编号
/// </summary>
public string RoleId { get; set; } /// <summary>
/// 角色
/// </summary>
public Role Role { get; set; } /// <summary>
/// 系统
/// </summary>
public List<Sys> Sys { get; set; } /// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { get; set; } /// <summary>
/// 性别
/// </summary>
public EnumGender Gender { get; set; }
}
/// <summary>
/// 角色表
/// </summary>
public class Role
{
/// <summary>
/// 角色名
/// </summary>
public string RoleName { get; set; } /// <summary>
/// 角色编号
/// </summary>
public string Id { get; set; } }
/// <summary>
/// 系统表
/// </summary>
public class Sys
{
/// <summary>
/// 系统名称
/// </summary>
public string SysName { get; set; } /// <summary>
/// 编号
/// </summary>
public string Id { get; set; }
}
/// <summary>
/// 性别
/// </summary>
[Flags]
public enum EnumGender
{
/// <summary>
/// 男
/// </summary>
Man = 1 << 0, /// <summary>
/// 女
/// </summary>
Women = 1 << 1,
}
然后我们先创建张三李四两个小伙伴
List<Manager> list = new List<Manager>();
List<Sys> Sys = new List<Sys>();
List<Sys> Sys2 = new List<Sys>();
Sys.Add(new Tests.Sys { Id = "1", SysName = "仓管系统" });
Sys.Add(new Tests.Sys { Id = "2", SysName = "人力资源系统" });
Sys2.Add(new Tests.Sys { Id = "1", SysName = "仓管系统" }); list.Add(new Manager { Id = "1", UserName = "张三", Tel = "18888888888", Gender = EnumGender.Man, RoleId = "1", CreateTime = DateTime.Parse("2021-9-22 10:50:50"), Sys = Sys, Role = new Role { RoleName = "超级管理员", Id = "1" } });
list.Add(new Manager { Id = "2", UserName = "李四", Tel = "16666666666", Gender = (EnumGender)3, RoleId = "2", CreateTime = DateTime.Parse("2021-9-21 10:50:50"), Sys = Sys2, Role = new Role { RoleName = "管理员", Id = "2" } });
数据结构图
在做查询前先让我们定义查询的Dto
/// <summary>
/// 查询参数实体
/// </summary> public class AllManagerDto : QueryPageModel
{
/// <summary>
/// 创建时间 开始(时间必须以Start结尾)
/// </summary>
public DateTime? CreateTimeStart { get; set; } /// <summary>
/// 创建时间 结束(结束时间必须以End结尾)
/// </summary>
public DateTime? CreateTimeEnd { get; set; }
/// <summary>
/// 创建时间(或者使用特性,约定方式)传值为("2021-9-21,2021-10-7")中间用,分割
/// </summary>
[Condition("CreateTime", EnumCondition.Between)]
public string CreateTime { get; set; }
/// <summary>
/// 角色编号
/// </summary>
[Condition("Role.Id", EnumCondition.In)]
public string RoleId { get; set; } /// <summary>
/// 角色名称
/// </summary> [Condition("Role.RoleName", EnumCondition.Contains)] public string RoleName { get; set; } /// <summary>
/// 系统名称
/// </summary> [Condition("Sys[SysName]", EnumCondition.Contains)] public string SysName { get; set; } /// <summary>
/// 名称
/// </summary>
public string UserName { get; set; } /// <summary>
/// 性别
/// </summary> public EnumGender? Gender { get; set; } [NotMapped]
public string AA { get; set; }
/// <summary>
/// 年龄 开始(必须以Min结尾)
/// </summary>
public int? AgeMin { get; set; } /// <summary>
/// 年龄 结尾(必须以Max结尾)
/// </summary>
public int? AgeMax{ get; set; }
}
我们来做一个简单的单表查询,查询完全满足,名字叫张三,号码为 18888888888,性别男,角色编号为“1”的,创建时间 大于 "2021-9-22" 的用户。我们只需要一句话就可以了,想想你以前的得写多少语句。
我们默认有以下约定 时间格式范围为 <=和>= ,数字 int decimal double等为 <=和>=,string 为包含
/// <summary>
/// 单表查询
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static List<Manager> GetAll(AllManagerDto input)
{
var list = GetList();
input.RoleId = "1";
input.Tel = "18888888888";
input.UserName = "张三";
input.Gender = EnumGender.Man;
input.CreateTimeStart = DateTime.Parse("2021-9-22"); var query = input.ToQueryModel<Manager>();
return list.AsQueryable().Where(query).ToList();
}
我们看看效果
生成的表达式
返回结果,是不是很神奇。
那如果我们要关联表查询呢,怎么破,别急,看下面代码
/// <summary>
/// 角色名称
/// </summary> [Condition("Role.RoleName", EnumCondition.Contains)] public string RoleName { get; set; } /// <summary>
/// 系统名称
/// </summary> [Condition("Sys[SysName]", EnumCondition.Contains)] public string SysName { get; set; }
我们使用 Condition 特性,标识 Role.RoleName 表示 查询Role下 RoleName 等于我们要查的数据,Sys[SysName] 表示用户表下Sys数组下名称为SysName 的条件

这就基本包含了我们所用到的情况。你是不是觉得漏了点什么,我们要处理排序怎么处理,别急,我们内置了添加排序的方法,我们还可以添加多个,完美把
/// <summary>
/// 添加排序条件
/// </summary>
/// <returns></returns>
public static BaseQueryModel AddOrderByItem(this BaseQueryModel queryModel, string propName, bool isDesc = true)
{
queryModel.OrderByItems.Add(new OrderByItem { PropName = propName, IsDesc = isDesc });
return queryModel;
}

还有个分组的特性,等有人问再说.......
表达式树扩展 动态生成表达式树插件 Sy.ExpressionBuilder。的更多相关文章
- 泛型方法动态生成表达式树 Expression
public string GetGridJSON(TraderInfo model) { IQueryable<TraderInfo> Temp = db.TraderInfo; if ...
- c# 表达式目录树拷贝对象(根据对象类型动态生成表达式目录树)
表达式目录树,在C#中用Expression标识,这里就不介绍表达式目录树是什么了,有兴趣可以自行百度搜索,网上资料还是很多的. 这里主要分享的是如何动态构建表达式目录树. 构建表达式目录树的代码挺简 ...
- ahjesus动态生成表达式树
直接上方法,看的懂的拿去用,看不懂的找资料看懂 , , Double floorprice = , Double topprice = , string brandstr = "" ...
- js动态生成JSON树
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- C#3.0新增功能10 表达式树 06 生成表达式
连载目录 [已更新最新开发文章,点击查看详细] 到目前为止,你所看到的所有表达式树都是由 C# 编译器创建的. 你所要做的是创建一个 lambda 表达式,将其分配给一个类型为 Expressi ...
- LinqToDB 源码分析——生成表达式树
当我们知道了Linq查询要用到的数据库信息之后.接下就是生成对应的表达式树.在前面的章节里面笔者就已经介绍过.生成表达式树是事实离不开IQueryable<T>接口.而处理表达式树离不开I ...
- Lind.DDD.ExpressionExtensions动态构建表达式树,实现对数据集的权限控制
回到目录 Lind.DDD框架里提出了对数据集的控制,某些权限的用户为某些表添加某些数据集的权限,具体实现是在一张表中存储用户ID,表名,检索字段,检索值和检索操作符,然后用户登陆后,通过自己权限来构 ...
- EF4.0、4.3创建表达式树状动态查询总结
---------------------------------------------快速适用 效果: where name like '%王%' and Age>=35 or Age< ...
- C# 表达式树 创建、生成、使用、lambda转成表达式树~表达式树的知识详解
笔者最近学了表达式树这一部分内容,为了加深理解,写文章巩固知识,如有错误,请评论指出~ 表达式树的概念 表达式树的创建有 Lambda法 和 组装法. 学习表达式树需要 委托.Lambda.Func& ...
随机推荐
- Mysql的行级锁
我们首先需要知道的一个大前提是:mysql的锁是由具体的存储引擎实现的.所以像Mysql的默认引擎MyISAM和第三方插件引擎 InnoDB的锁实现机制是有区别的. Mysql有三种级别的锁定:表级锁 ...
- 【JavaScript】创建全0的Array
1.创建一个长度为m的全0数组 var arr = new Array(m).fill(0); 2.创建一个m行n列的全0数组 var arr = new Array(m).fill(new Arra ...
- numpy基础教程--对数组进行水平拼接和竖直拼接
在处理数组的时候经常要用到拼接,numpy中有两个非常实用的函数,可以快捷对数组进行拼接 1.hstack(tup)函数可以接收维度相同的数组,进行水平拼接. 2.vstack(tup)用来竖直拼接 ...
- scrapy爬取招聘网站,items转换成dict遇到的问题
pipelines代码 1 import json 2 3 class TencentJsonPipeline(object): 4 def __init__(self): 5 self.file = ...
- JDK各版本新增的主要特性总结
JDK1.5新特性: 1.自动装箱与拆箱: 2.枚举 3.静态导入,如:import staticjava.lang.System.out 4.可变参数(Varargs) 5.内省(Introspec ...
- C#ADO.NET技术总结
[ADO.NET的主要组件-..NET framework数据提供程序和DataSet(数据集)] 一.DataSet数据集负责对数据库执行命令. 二.NET framework数据提供程序的四个核心 ...
- Mysql报错合集
目录 一.链接报错 客户端连接mysql出错 链接客户端出错 交互登陆mysql出现warning警告Using a password 导入数据到数据库报错ERROR 1050 登陆数据库提示-bas ...
- [BUUCTF]REVERSE——新年快乐
新年快乐 附件 例行查壳儿,32位程序,upx加壳儿 利用网上找到的脱壳儿工具,拿到了去壳儿后的程序 32位ida打开,shift+f12查看程序里的字符串,得到了关于flag的提示 双击,ctrl+ ...
- WPF之交互触发器(CallMethodAction)学习
需求背景: 当我们需要制作画板时,我们的VM需要记录我们的坐标并保存到Path的Data中,用我们普通的Command是无法办到的,这时我们就衍生出来了一个交互触发器CallMethodAction ...
- WebRTC + WebSocket 实现视频通话
前言 WebRTC WebRTC(Web Real-Time Communication).Real-Time Communication,实时通讯. WebRTC能让web应用和站点之间选择性地分享 ...