全局过滤器的作用是设置 一个查询条件 ,当你查询操作的时候满足这个条件,那么你的查询就会附加你设置的条件
应用场景:过滤假删除数据 比如 每个查询后面都要加 isdelete=false
根据实体添加过滤器,只要是这个实体的Queryable操作都会生效
/***过滤器写的位置***/ 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+'%')
请升级5.1.3.47及以上版本
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();//还原过滤器 (适合下面代码还需要过滤器情况)
//追加在on后面 db.QueryFilter.AddTableFilter<Order>(it=>it.Id==1) //追加在where后面 db.QueryFilter.AddTableFilter<Order>(it=>it.Id==1,QueryFilterProvider.FilterJoinPosition.Where)
1.3.1 继承接口全局添加
//需要升级到 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.3.2 动态过滤器( 接口和类都可以) 5.1.4.106-preview13+
//程序启动时注册 (需要安装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种模式
//删除 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()//不支持全局设置需要手动处理
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();
SqlFunc.Subqueryable<Order>().EnableTableFilter().Where(s=>s.id==it.xx).Any()
On是加到On后面 (默认符合多数情况)
db.QueryFilter.AddTableFilter<Order>(it => it.Id == 1, QueryFilterProvider.FilterJoinPosition.On);
Where是加到Where后面 (LeftJoin需要根据从表强制过滤主表才用)
db.QueryFilter.AddTableFilter<Order>(it => it.Id == 1, QueryFilterProvider.FilterJoinPosition.Where);
唯一优点不依赖实体,使用了过滤器所有 Queryable的 sql都会加上这一句
//表单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 //多表生效 }); //可以用清空所有来清空
表过滤器老版本写法
//老版本 //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、
针对一对一并且是单主键关联进行了优化(只优化了一对一并且是单主键)
因为主键是唯一的所以根本就不需要过滤器
目前所有用户都满足这个优化条件
如果你有新的疑虑可以看下面讨论
https://www.donet5.com/Ask/9/27289
当前是介绍查询条件过滤,如果你想用AOP等功能可以看
https://www.donet5.com/Home/Doc?typeId=1204
2016 © donet5.comApache Licence 2.0