全局过滤器的作用是 设置 一个查询条件 ,当你使用查询操作的时候满足这个条件,那么你的语句就会附加你设置的条件
应用场景:过滤假删除数据 比如 每个查询后面都要加 isdelete=false
根据实体添加过滤器,只要是这个实体的Queryable操作都会生效
/***过滤器写的位置***/ SqlSugarClient Db= new SqlSugarClient(new ConnectionConfig(){ ConnectionString = "连接符字串", DbType = DbType.SqlServer, IsAutoCloseConnection = true}, db=>{ //过滤器写在这儿就行了 db.QueryFilter.AddTableFilter<Order>(it => it.Name.Contains("a")); //如果是多租户 //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 无接口动态添加
这种方式是应用第三方库进行字符串转表达式,能够处理相对复杂的逻辑
Expression<Func<Order, bool>> dynamicExpression = it => it.Name=="b";//动态构造这种表达式 Expression exp = dynamicExpression; Type type = typeof(Order); db.QueryFilter.AddTableFilter(type,exp);//新语法5.1.3.33 //老语法 // db.QueryFilter.Add(new TableFilterItem<object>(type, exp ,true)); db.Queryable<Order>().ToList();
具体实现:
//从程序集拿到实体type集合 Type[] types= Assembly .LoadFrom("XXX.dll")//如果 .dll报错,可以换成 xxx.exe 有些生成的是exe .GetTypes().Where(it=>it.FullName.Contains("OrmTest."))//命名空间过滤,当然你也可以写其他条件过滤 ToArray();//断点调试一下是不是需要的Type,不是需要的在进行过滤 // 遍历实体类 foreach(var entityType in types){ if(!entityType.GetProperty("IsDeleted").IsEmpty()){ //判断实体类中包含IsDeleted属性 //构建动态Lambda var lambda = DynamicExpressionParser.ParseLambda (new[] { Expression.Parameter(entityType, "it") }, typeof(bool), $"{nameof(EntityBase.IsDeleted)} == @0", false); db.QueryFilter.AddTableFilter(entityType,lambda);//新语法5.1.3.33 //老版本 //db.QueryFilter.Add(new TableFilterItem<object>(entityType, lambda,true));//将Lambda传入过滤器 } // 租户动态处理,同上 } //DynamicExpressionParser 对象来自 System.Linq.Dynamic.Core
查询是配置就生效,更新和删除要分自动和手动2种模式
//删除 db.Deleteable<Order>().EnableQueryFilter()//启用过滤器 .Where(it => it.Id == 0) .ExecuteCommand(); //更新:只支持表达式方式更新 (如果实体方式更新建议先查询在更新) db.Updateable<Order>().EnableQueryFilter()//启用过滤器 .SetColumns(it => it.Name == "a") .Where(it => it.Id == 1) .ExecuteCommand();
DbType = DbType.SqlServer, ConnectionString = Config.ConnectionString, IsAutoCloseConnection = true, MoreSettings=new ConnMoreSettings { IsAutoDeleteQueryFilter=true,//启用删除查询过滤器 IsAutoUpdateQueryFilter=true//启用更新查询过滤器 (表达式更新,如果是实体方式更新建议先查询在更新) }
SqlFunc.Subqueryable<Order>().EnableTableFilter().Where(s=>s.id==it.xx).Any()
唯一优点不依赖实体,使用了过滤器所有 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();
当前是介绍查询条件过滤,如果你想用AOP等功能可以看
https://www.donet5.com/Home/Doc?typeId=1204
2016 © donet5.comApache Licence 2.0