【过滤器】.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 系列
相关推荐
珹洺18 分钟前
C++从入门到实战(十)类和对象(最终部分)static成员,内部类,匿名对象与对象拷贝时的编译器优化详解
java·数据结构·c++·redis·后端·算法·链表
weixin_4825655326 分钟前
USB有驱IC卡读卡器
c#
ai大师1 小时前
给聊天机器人装“短期记忆“:Flask版实现指南
后端·python·gpt·flask·oneapi·中转api·apikey
Hellc0071 小时前
SignalR 完全指南:.NET 实时通信的终极解决方案
.net
galileo20161 小时前
rust服务应用开发框架
后端·rust
闪电麦坤954 小时前
C#:Time.deltaTime
开发语言·c#
codingandsleeping7 小时前
浏览器的缓存机制
前端·后端
追逐时光者8 小时前
面试官问:你知道 C# 单例模式有哪几种常用的实现方式?
后端·.net
Asthenia04128 小时前
Numpy:数组生成/modf/sum/输出格式规则
后端
Asthenia04128 小时前
NumPy:数组加法/数组比较/数组重塑/数组切片
后端