表达式树扩展 动态生成表达式树插件 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& ...
随机推荐
- vue引入d3
单页面使用 cnpm install d3 --save-dev 指定版本安装 cnpm install d3@6.3.1 -S <script> import * as d3 from ...
- hash 模式与 history 模式小记
hash 模式 这里的 hash 就是指 url 后的 # 号以及后面的字符.比如说 "www.baidu.com/#hashhash" ,其中 "#hashhash&q ...
- 【Python】【Module】re
python中re模块提供了正则表达式相关操作 字符: . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线或汉字 \s 匹配任意的空白符 \d 匹配数字 \b 匹配单词的开始或结束 ^ 匹配 ...
- Next_day()函数的用法
一.定义 NEXT_DAY(date,char) date参数为日期型, char:为1~7或Monday/Mon~Sunday/ 指定时间的下一个星期几(由char指定)所在的日期, c ...
- 【C/C++】引用&的含义/语法/作为函数参数/函数返回值/本质/常量引用
含义 引用不产生副本,只是给原变量起了别名. 对引用变量的操作就是对原变量的操作. 基本语法 数据类型 &别名 = 原名 e.g. int a = 10; int &b = a; // ...
- ASP.NET Web API路由解析
前言 本篇文章比较长,仔细思考阅读下来大约需要15分钟,涉及类图有可能在手机显示不完整,可以切换电脑版阅读. 做.Net有好几年时间了从ASP.NET WebForm到ASP.NET MVC再到ASP ...
- C#汽车租赁系统
类图: 父类(车类,抽象类) /// <summary> /// 车辆基本信息类.搞一个抽象类玩玩 /// </summary> public abstract class V ...
- [BUUCTF]PWN——babyheap_0ctf_2017
[BUUCTF]PWN--babyheap_0ctf_2017 附件 步骤: 例行检查,64位,保护全开 试运行一下程序,看到这个布局菜单,知道了这是一道堆的题目,第一次接触堆的小伙伴可以去看一下这个 ...
- Notepad++ 常用功能:批量取消替换换行、强制刷新数据
批量取消替换换行 换行批量替换成空格 Ctrl+F 打开查找替换窗口,使用:\r\n 替换成 空格,全部替换 强制刷新数据源,重新加载数据 快捷键:Ctrl+R 或者 Alt+F 然后 L 或者点击菜 ...
- Log4j2又爆雷!2.16.0存在DOS风险,升级2.17.0可解决
本以为,经过上周的2.16.0版本升级,Log4j2的漏洞修复工作,大家基本都要告一段落了. 万万没想到,就在周末,Log4j官方又发布了新版本:2.17.0 该版本主要修复安全漏洞:CVE-2021 ...