# 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; }
}
```