【过滤器】.NET开源 ORM 框架 SqlSugar 系列

目录

[0、 过滤器介绍](#0、 过滤器介绍)

[1、表过滤器 (推荐)](#1、表过滤器 (推荐))

[1.1 手动添加过滤器](#1.1 手动添加过滤器)

[1.2 禁用、清空、备份和还原](#1.2 禁用、清空、备份和还原)

[1.3 联表查询设置](#1.3 联表查询设置)

[1.4 动态添加](#1.4 动态添加)

2、修改和删除用过滤器

[2.1 局部设置](#2.1 局部设置)

[2.2 全局设置 (5.1.4.62)](#2.2 全局设置 (5.1.4.62))

3、子查询用过滤器

4、联表过滤器位置配置

[5、 不依赖实体过滤器](#5、 不依赖实体过滤器)

6、老版本写法

7、导航过滤器疑问


0、 过滤器介绍

🎯全局过滤器的作用是设置 一个查询条件 ,当你查询操作的时候满足这个条件,那么你的查询就会附加你设置的条件。

📍应用场景: 过滤 假删除 数据 比如 每个查询后面都要加 isdelete=false

1、表过滤器 (推荐)

1.1 手动添加过滤器

根据实体添加过滤器,只要是这个实体的 Queryable 操作都会生效。

javascript 复制代码
/***过滤器写的位置***/
SqlSugarClient Db= new SqlSugarClient(new ConnectionConfig(){
           ConnectionString = "连接符字串", 
           DbType = DbType.SqlServer,
           IsAutoCloseConnection = true},
           db=>{
                   
               //过滤器写在这儿就行了
               db.QueryFilter.AddTableFilter<IDeleted>(it => it.IsDeleted==false);
               //如果是多租户
               //db.GetConnection(XXX).AddTableFilter 
               //用GetConnection还是GetConnectionScope和你代码要保持一致
           });
            
            
            
/***具体用例***/           
 
db.QueryFilter.AddTableFilter<Order>(it => it.Name.Contains("a"));
db.QueryFilter.AddTableFilterIF<Order>( isAdmin == false ,it => it.Name.Contains("a"));
 
 
//接口过滤器 (继承接口的类都有效) 请升级 5.1.3.47
db.QueryFilter.AddTableFilter<IDeleted>(it => it.IsDelete==false);
 
   
/****用例讲解***/
db.QueryFilter.AddTableFilter<Order>(it => it.Name.Contains("a"));//给Order类型加一个过滤器
 
//单表有效
db.Queryable<Order>().ToList();
// SELECT [Id],[Name],[Price],[CreateTime],[CustomId] FROM [Order]  WHERE  ([Name] like '%'+@MethodConst0+'%') 
 
//多表查询也有效
db.Queryable<OrderItem>().LeftJoin<Order>((i, o) => i.OrderId == o.Id)
        .Select((i,o)=>i).ToList();
//SELECT i.* FROM [OrderDetail] i Left Join [Order]  o  
//ON ( [i].[OrderId] = [o].[Id] )  AND  ([o].[Name] like '%'+@MethodConst1+'%')

1.2 禁用、清空、备份和还原

📤提示:请升级5.1.3.47及以上版本

javascript 复制代码
db.QueryFilter
.AddTableFilter<IDeletedFilter>(it => it.IsDeleted==false)//IDeletedFilter是自定义接口,继承这个接口的实体有效
.AddTableFilterIF<ITenantFilter>(isAdmint==false,it=>it.OrgId==用户OrgId);//ITenantFilter自定义接口
 
//用例1:单条语句清空,只影响当前语句
db.Queryable<Order>().ClearFilter().ToList();//所有过滤器都无效
db.Queryable<Order>().ClearFilter<IDeletedFilter>().ToList();//只有IDeletedFilter过滤器无效
db.Queryable<Order>().ClearFilter<IDeletedFilter,ITenantFilter>().ToList();//IDeletedFilter+ITenantFilter无效
   
//用例2:当前上下文清空 ,不会影响其他请求,只是当前请求清空
db.QueryFilter.Clear();
db.QueryFilter.Clear<IDeletedFilter>(); 
 
//用例3:清空并还原 ,不会影响其他请求,只是当前请求清空
db.QueryFilter.ClearAndBackup();//有多个重载 ClearAndBackup<T,T2>();
db.Queryable<Order>().ToList();
db.QueryFilter.Restore();//还原过滤器 (适合下面代码还需要过滤器情况)

1.3 联表查询设置

javascript 复制代码
//追加在on后面
db.QueryFilter.AddTableFilter<Order>(it=>it.Id==1)
//追加在where后面
db.QueryFilter.AddTableFilter<Order>(it=>it.Id==1,QueryFilterProvider.FilterJoinPosition.Where)

1.4 动态添加

1.4.1 继承接口全局添加

javascript 复制代码
//需要升级到 5.1.3.46-preview10 
db.QueryFilter.AddTableFilter<IDeleted>(it => it.IsDelete==false);
//符合条件执行过滤器
db.QueryFilter.AddTableFilterIF<IDeleted>(IsFilter==true ,it => it.IsDelete==false);
 
//实体类继承该接口就有效
public interface IDeleted
{
   public bool IsDelete{get;set;}
}

1.4.2 动态过滤器( 接口和类都可以)

📤提示: 5.1.4.106-preview13+

javascript 复制代码
//程序启动时注册 (需要安装Dynamic.Core组件)
StaticConfig.DynamicExpressionParserType = typeof(DynamicExpressionParser);
 
 //注意:第二个参数必须要有$
 //参数化:可以缓存创建性能好
 //如果没有$ 需要用 FormattableStringFactory.Create("it=>it.Id=={0}", 1)  
 
//调用如下 (Type可以是接口 也可以是类)
db.QueryFilter
.AddTableFilter(typeof(IUser), "it", $"it=>it.UserName={ "jack" } ")//一定要用$"{}"方式给参数赋值
.AddTableFilter(typeof(IOrg), "it", $" it=> it.OrgId={1} || it.OrgId={2}  ");//一定要用$"{}"方式给参数赋值
 
//常用的C#方法都可以用 如Contains、时间.Date、时间.ToString("yyyy-MM-dd")  
//如果要用SqlFunc方法:
//https://www.donet5.com/Home/Doc?typeId=2569

2、修改和删除用过滤器

🔎查询是配置就生效,更新和删除要分自动和手动2种模式。

2.1 局部设置

javascript 复制代码
//删除
 db.Deleteable<Order>().EnableQueryFilter()//启用过滤器
 .Where(it => it.Id == 0)
 .ExecuteCommand();//支持全局设置2.1
  
//表达式方式更新
  db.Updateable<Order>().EnableQueryFilter()//启用过滤器
  .SetColumns(it => it.Name == "a")
  .Where(it => it.Id == 1)
  .ExecuteCommand();//支持全局设置 2.1
   
//对象方式更新 5.1.4.106-preview09++ 
db.Updateable(updateObj)
.PageSize(1)//需要一条一条更新才能用过滤器
.EnableQueryFilter().ExecuteCommand()//不支持全局设置需要手动处理

2.2 全局设置 (5.1.4.62)

javascript 复制代码
 DbType = DbType.SqlServer,
 ConnectionString = Config.ConnectionString,
 IsAutoCloseConnection = true,
 MoreSettings=new ConnMoreSettings 
 { 
      IsAutoDeleteQueryFilter=true,//启用删除查询过滤器  
      IsAutoUpdateQueryFilter=true//启用更新查询过滤器 (表达式更新,如果是实体方式更新建议先查询在更新)
 }
  
 //清空过滤器 当前上下文有限 (全局设置可以这样清空)
 db.QueryFilter.Clear();
 db.Deleteable<Order>().Where(it => it.Id == 0).ExecuteCommand();

3、子查询用过滤器

javascript 复制代码
SqlFunc.Subqueryable<Order>().EnableTableFilter().Where(s=>s.id==it.xx).Any()

4、联表过滤器位置配置

✏️ On 是加到 On 后面 (默认符合多数情况)

javascript 复制代码
 db.QueryFilter.AddTableFilter<Order>(it => it.Id == 1, QueryFilterProvider.FilterJoinPosition.On);

✏️ Where 是加到 Where 后面 ( LeftJoin 需要根据 从表 强制过滤主表 才用)

javascript 复制代码
 db.QueryFilter.AddTableFilter<Order>(it => it.Id == 1, QueryFilterProvider.FilterJoinPosition.Where);

5、 不依赖实体过滤器

🎖️唯一优点 不依赖 实体,使用了 过滤器 所有 Queryable 的 sql 都会加上这一句。

javascript 复制代码
 //表单Queryable查询
 db2.QueryFilter.Add(new SqlFilterItem()
            {
                FilterValue = it =>
                {
                    //Writable logic
                    return new SqlFilterResult() { Sql = " name like '%a%' " };
                },
                IsJoinQuery = false // 单表生效  
            });
 //多表Queryable查询           
 db2.QueryFilter.Add(new SqlFilterItem()
            {
                FilterValue = it =>
                {
                    //Writable logic
                    return new SqlFilterResult() { Sql = " o.name like '%a%' " };
                },
                IsJoinQuery = true //多表生效
 });
  
 //可以用清空所有来清空

6、老版本写法

🕰️表过滤器老版本写法

javascript 复制代码
//老版本
//db.QueryFilter.Add(new TableFilterItem<Order>(it => it.Name.Contains("a"),true))//true表示Leftjoin加on后面
 
//技巧:表过滤器使用Sql语句
//db.QueryFilter.AddTableFilter(it => SqlFunc.MappingColumn(default(bool),"id=1");
 
//清除过滤器
//db.Queryable<Order>().Filter(null,true).ToList();7、

7、导航过滤器疑问

✅针对一对一并且是 单主键关联进行了优化(只优化了一对一并且是单主键)

✅因为主键是唯一的所以根本就不需要过滤器

✅目前所有用户都满足这个优化条件


.NET开源 ORM 框架 SqlSugar 系列

  1. 【开篇】.NET开源 ORM 框架 SqlSugar 系列
  2. 【入门必看】.NET开源 ORM 框架 SqlSugar 系列
  3. 【实体配置】.NET开源 ORM 框架 SqlSugar 系列
  4. 【Db First】.NET开源 ORM 框架 SqlSugar 系列
  5. 【Code First】.NET开源 ORM 框架 SqlSugar 系列
  6. 【数据事务】.NET开源 ORM 框架 SqlSugar 系列
  7. 【连接池】.NET开源 ORM 框架 SqlSugar 系列
  8. 【查询目录】.NET开源 ORM 框架 SqlSugar 系列
  9. 【查询基础】.NET开源 ORM 框架 SqlSugar 系列
  10. 【排序用法】.NET开源 ORM 框架 SqlSugar 系列
  11. 【分组去重】.NET开源 ORM 框架 SqlSugar 系列
  12. 【联表查询】.NET开源 ORM 框架 SqlSugar 系列
  13. 【导航查询】.NET开源 ORM 框架 SqlSugar 系列
  14. 【子查询】.NET开源 ORM 框架 SqlSugar 系列
  15. 【嵌套查询】.NET开源 ORM 框架 SqlSugar 系列
  16. 【配置查询】.NET开源 ORM 框架 SqlSugar 系列
  17. 【并集查询】.NET开源 ORM 框架 SqlSugar 系列
  18. 【树型查询】.NET开源 ORM 框架 SqlSugar 系列
  19. 【表格查询】.NET开源 ORM 框架 SqlSugar 系列
相关推荐
前端付豪4 分钟前
揭秘网易统一日志采集与故障定位平台揭秘:如何在亿级请求中1分钟定位线上异常
前端·后端·架构
陈随易21 分钟前
Lodash 杀手来了!es-toolkit v1.39.0 已完全兼容4年未更新的 Lodash
前端·后端·程序员
喵个咪32 分钟前
开箱即用的GO后台管理系统 Kratos Admin - 代码生成工具集
微服务·orm·protobuf
未来影子39 分钟前
SpringAI(GA):Nacos3下的分布式MCP
后端·架构·ai编程
Hockor1 小时前
写给前端的 Python 教程三(字符串驻留和小整数池)
前端·后端·python
码农之王1 小时前
记录一次,利用AI DeepSeek,解决工作中算法和无限级树模型问题
后端·算法
Wo3Shi4七1 小时前
消息不丢失:生产者收到写入成功响应后消息一定不会丢失吗?
后端·kafka·消息队列
爱上语文1 小时前
MyBatisPlus(3):常用配置
java·后端·mybatis
编程乐趣1 小时前
C#实现Stdio通信方式的MCP Server
后端
程序猿本员1 小时前
线程池精华
c++·后端