# BaseQuery **Repository Path**: ArchitectAllen/base-query ## Basic Information - **Project Name**: BaseQuery - **Description**: 写最少的表达式查询 - **Primary Language**: C# - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2022-03-28 - **Last Updated**: 2023-02-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # BaseQuery #### 介绍 QueryBase 可以结合多款ORM框架使用.如果你为重复的写着ORM的查询表达式而苦恼,那么你需要的正是这样一个框架.基础的查询条件都帮你封装好了.额外的条件,可以只用增加查询实体的属性来控制,本着`约定大于配置的理念`,不做任何配置,只从命名规范上去区分,直观简洁明了.以最简单的方式开发. #### 使用说明 ##### QuickStart 1. 引用nuget ``` shell dotnet add package BaseQuery ``` 2. 添加ORM,以SqlSugar为例 ``` shell dotnet add package SqlSugarCore ``` 3. 添加如下实体 ``` C# /// /// 学生实体 /// [SugarTable("Student", TableDescription = "学生表")] public class StudentEntity { /// /// 姓名 /// public string Name { get; set; } /// /// 学号 /// public string Code { get; set; } /// /// 年龄 /// public int? Age { get; set; } /// /// 性别 /// [SugarColumn(IsNullable = true)] public int? Sex { get; set; } /// /// 学校Id /// public int? SchoolId { get; set; } } /// /// 学生查询 /// public class StudentQueryInput : StudentEntity { /// /// 包含xx名称--后缀[Contains] /// public string NameContains { get; set; } /// /// 名称以xx开头--后缀[StartsWith] /// public string NameStartsWith { get; set; } /// /// 名称以xx结尾--后缀[EndsWith] /// public string NameEndsWith { get; set; } /// /// 集合包含---后缀[_Contains] /// public List Name_Contains { get; set; } /// /// 集合包含---后缀[_Contains] /// public string[] Code_Contains { get; set; } /// /// 集合包含---后缀[_Contains] /// public IEnumerable CreateUserId_Contains { get; set; } /// /// 集合包含---后缀[_Contains] /// public int?[] Age_Contains { get; set; } /// /// 集合包含---后缀[_Contains] /// public IEnumerable Sex_Contains { get; set; } /// /// 错误示范 实体定义的是int? 这边定义int 是不行的. /// //public List Age_Contains { get; set; } } ``` 4. 注册 ORM-SqlSugar、BaseQuery-BaseDynamicExpression ``` C# builder.Services.AddTransient(typeof(BaseDynamicExpression<,>)); builder.Services.AddSingleton(_ => new SqlSugarScope(new ConnectionConfig() { //ConfigId="db01" 多租户用到 ConnectionString = builder.Configuration.GetConnectionString("mysql"), DbType = DbType.MySql, IsAutoCloseConnection = true//自动释放 })); ``` 5. 添加学生Controller, - 方法`GetQueryable`是BaseQuery的封装使用. - `GetEntityListAsync`,这边直接返回Sql. - 所有的查询都在`StudentQueryInput`管控. - 四不四很简单.后面还可以配合多表使用. ``` C# /// /// 学生 /// [ApiController] [Route("[controller]")] public class StudentController : ControllerBase { private readonly ILogger _logger; private readonly BaseDynamicExpression _expression; private readonly ISqlSugarClient _db; public StudentController(ILogger logger, BaseDynamicExpression expression, ISqlSugarClient db) { _logger = logger; _expression = expression; _db = db; } [HttpPost(Name = "GetEntityList")] public KeyValuePair> GetEntityListAsync(StudentQueryInput input) { return this.GetQueryable(input).ToSql(); } private ISugarQueryable GetQueryable(StudentQueryInput input) { var res = _expression.GetExpression(input); return _db.Queryable().WhereIF(res.Condition, res.Expression); } } ``` - [QuickStart源码](https://gitee.com/ArchitectAllen/base-query-quick-start) ##### 完整封装示例 以SqlSugar为例 ``` C# /// /// [单表]获取集合 /// /// /// public async Task> GetEntityListAsync(R input) { return await this.GetSqlSugarExpression(input).ToListAsync(); } /// /// [单表]获取单个 /// /// /// public async Task GetEntityAsync(R input) { return await this.GetSqlSugarExpression(input).FirstAsync(); } /// /// [单表]获取分页 /// /// /// public async Task> GetPageEntityListAsync(PageEntity input) { var res = this.GetSqlSugarExpression(input.Data); if (!string.IsNullOrEmpty(input.OrderField)) res.OrderBy(input.OrderField); return await res.ToPageListAsync(input.PageIndex, input.PageSize, input.Total); } /// /// 获取SqlSugar的表达式目录树 /// /// /// private ISugarQueryable GetSqlSugarExpression(R input) { var res = GetExpression(input); return _db.Queryable().WhereIF(res.Condition, res.Expression); } ``` - [详解](https://www.cnblogs.com/vsnb/p/16069606.html) - [Demo](https://gitee.com/ArchitectAllen/base-query-demo.git) #### 查询实体命名规范说明 - 首先,正确的Linq查询,是建立在类型一致的基础上的.所以关联的字段,类型必须一致 - `=`:名称类型一致 - 小于(<):名称相同+入参字段后缀`LessThan` > 查询实体属性: public int IdLessThan { get; set; } - 小于等于(<=):名称相同+入参字段后缀`LessThanOrEqual` > 查询实体属性: public int IdLessThanOrEqual { get; set; } - 大于(>):名称相同+入参字段后缀`GreaterThan` > 查询实体属性: public int IdGreaterThan { get; set; } - 大于等于(>=):名称相同+入参字段后缀`GreaterThanOrEqual` > 查询实体属性: public int IdGreaterThanOrEqual { get; set; } - 不等于(<>/!=):名称相同+入参字段后缀`NotEqual` > 查询实体属性: public int IdNotEqual { get; set; } public string NameNotEqual { get; set; } - `Contains(Like)`:类型一致+名称相同+后缀`Contains` - `StartsWith`:名称相同+入参字段后缀`StartsWith` - `EndsWith`:名称相同+入参字段后缀`EndsWith` - 集合(IN): 名称相同+入参字段后缀`_Contains` ``` C# /// /// 实体 /// public class SchoolEntity { /// /// 学校名称 /// public string Name { get; set; } } /// /// 查询入参 /// public class SchoolQueryInput { /// /// =名称类型一致 /// public string Name { get; set; } /// /// 类型一致+后缀Contains /// public string NameContains { get; set; } /// /// 类型一致+后缀StartsWith /// public string NameStartsWith { get; set; } /// /// 类型一致+后缀EndsWith /// public string NameEndsWith { get; set; } /// /// 类型一致+后缀_Contains /// public List Name_Contains { get; set; } } ```