作为还在CURD中的一员,查询我感觉还是很烦人的一个浪费时间的工作,我经历过远古时代的GetAll(string name,int age),这种方式写服务的时候真的是心中一万个草泥马飞过,后面逐渐的变成了传一个实体GetAll([FromQuery] GetDto)似乎也能默默的忍受,然后含泪写着一堆的WhereIf,目前这种方式应该还是很多人在用的一种方式。然而 Sy.expressionParser的出现,我们有了更好的选择。
为了方便后面的介绍,先让我们有几个实体,用户表,角色表,系统表,我们约定一个用户只有一种角色,但是可以存在多个系统中。
////// 用户表 /// public class Manager { ////// 编号 /// public string Id { get; set; } ////// 名称 /// public string Name { get; set; } ////// 手机 /// public string Tel { get; set; } ////// 角色编号 /// public string RoleId { get; set; } ////// 角色 /// public Role Role { get; set; } ////// 系统 /// public ListSys { get; set; } /// /// 创建时间 /// public DateTime CreateTime { get; set; } ////// 性别 /// public EnumGender Gender { get; set; } }
////// 角色表 /// public class Role { ////// 角色名 /// public string RoleName { get; set; } ////// 角色编号 /// public string Id { get; set; } }
////// 系统表 /// public class Sys { ////// 系统名称 /// public string SysName { get; set; } ////// 编号 /// public string Id { get; set; } }
////// 性别 /// [Flags] public enum EnumGender { ////// 男 /// Man = 1 << 0, ////// 女 /// Women = 1 << 1, }
然后我们先创建张三李四两个小伙伴
Listlist = new List (); List Sys = new List (); List Sys2 = new List (); 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
////// 查询参数实体 /// public class AllManagerDto : Querybase { ////// 创建时间 开始(时间必须以Start结尾) /// public DateTime? CreateTimeStart { get; set; } ////// 创建时间 结束(结束时间必须以End结尾) /// public DateTime? CreateTimeEnd { get; set; }
////// 创建时间(或者使用特性,约定方式)传值为("2021-9-21,2021-10-7")中间用,分割 /// [Condition("CreateTime", EnumCondition.Between)] public string CreateTime { get; set; }
////// 角色编号 /// [Condition("Role.Id", EnumCondition.In)] public string RoleId { get; set; } ////// 角色名称 /// [Condition("Role.RoleName", EnumCondition.Contains)] public string RoleName { get; set; } ////// 系统名称 /// [Condition("Sys[SysName]", EnumCondition.Contains)] public string SysName { get; set; } ////// 名称 /// public string UserName { get; set; } ////// 性别 /// public EnumGender? Gender { get; set; } [NotMapped] public string AA { get; set; }
////// 年龄 开始(必须以Min结尾) /// public int? AgeMin { get; set; } ////// 年龄 结尾(必须以Max结尾) /// public int? AgeMax{ get; set; }
}
我们来做一个简单的单表查询,查询完全满足,名字叫张三,号码为 18888888888,性别男,角色编号为“1”的,创建时间 大于 "2021-9-22" 的用户。我们只需要一句话就可以了,想想你以前的得写多少语句。
我们默认有以下约定 时间格式范围为 <=和>= ,数字 int decimal double等为 <=和>=,string 为包含
////// 单表查询 /// /// ///public static List 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 (); return list.AsQueryable().Where(query).ToList(); }
我们看看效果
生成的表达式
返回结果,是不是很神奇。
那如果我们要关联表查询呢,怎么破,别急,看下面代码
////// 角色名称 /// [Condition("Role.RoleName", EnumCondition.Contains)] public string RoleName { get; set; } ////// 系统名称 /// [Condition("Sys[SysName]", EnumCondition.Contains)] public string SysName { get; set; }
我们使用 Condition 特性,标识 Role.RoleName 表示 查询Role下 RoleName 等于我们要查的数据,Sys[SysName] 表示用户表下Sys数组下名称为SysName 的条件
这就基本包含了我们所用到的情况。你是不是觉得漏了点什么,我们要处理排序怎么处理,别急,我们内置了添加排序的方法,我们还可以添加多个,完美把
////// 添加排序条件 /// ///public static baseQueryModel AddOrderByItem(this baseQueryModel queryModel, string propName, bool isDesc = true) { queryModel.OrderByItems.Add(new OrderByItem { PropName = propName, IsDesc = isDesc }); return queryModel; }
至此,我们的插件的基本用法就差不多了。



