sqlsugar表过滤filter探究
sqlsugar支持表过滤器,如果表里面有这个字段,则可以自动添加sql语句过滤
但是有一些疑问,就是如果表没有这个字段会自动添加么,肯定是不会,但是有时候脑袋就是钻牛角尖,总感觉会加语句,所以找了点时间看了下源码。
试图搞清楚里面的逻辑
所以如何是如何添加过滤字段的呢,有较多的方式添加,许多框架基本都是这种用法,例如 admin.net 中的代码
SqlSugarScope sqlSugar = new(dbOptions.ConnectionConfigs.Adapt<List<ConnectionConfig>>(), db =>
{
dbOptions.ConnectionConfigs.ForEach(config =>
{
var dbProvider = db.GetConnectionScope(config.ConfigId);
SetDbAop(dbProvider, dbOptions.EnableConsoleSql);
SetDbDiffLog(dbProvider, config);
});
});
其中SetDbAop 设置db过滤 其中代码 :
// 配置租户过滤器
var tenantId = App.User?.FindFirst(ClaimConst.TenantId)?.Value;
if (!string.IsNullOrWhiteSpace(tenantId))
db.QueryFilter.AddTableFilter<ITenantIdFilter>(u => u.TenantId == long.Parse(tenantId));
添加租户字段过滤 ,多租户必备字段,让我们在业务中无需考虑隔离问题。但是这个东西是如何运行的还是需要研究一下。
于是顺藤摸瓜,沿着方法一路找就好了,但是前提是我们下载了sqlsugar的源码,好在它也是开源的,直接下载源码即可
可以看到 AddTableFilter=>调用了Add(filter);
public QueryFilterProvider AddTableFilter<T>(Expression<Func<T, bool>> expression, FilterJoinPosition filterJoinType = FilterJoinPosition.On)
{
bool isJoinOn = filterJoinType == FilterJoinPosition.On;
TableFilterItem<T> filter = new TableFilterItem<T>(expression, isJoinOn);
Add(filter);
return this;
}
public IFilter Add(SqlFilterItem filter)
{
if (_Filters == null)
{
_Filters = new List<SqlFilterItem>();
}
_Filters.Add(filter);
return this;
}
private List<SqlFilterItem> _Filters { get; set; }
其将 过滤注入了 _Filters
_Filters是私有的,肯定有向外展示的字段 ,为GeFilterList
public List<SqlFilterItem> GeFilterList
{
get
{
if (_Filters == null)
_Filters = new List<SqlFilterItem>();
return _Filters;
}
}
直接查看该字段的引用 九个
不多,慢慢找就找到了 ,加上我们的注释
public string GetValue(Expression expression)
{
var result = "";
if (this.Context.SugarContext != null)
{
var db = this.Context.SugarContext.Context;
BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
//当前表类型
Type type = this.Context.SubTableType;
var isWhere = HasWhere;
if (db.QueryFilter.GeFilterList != null) {
foreach (var item in db.QueryFilter.GeFilterList)
{
PropertyInfo field = item.GetType().GetProperty("exp", flag);
if (field != null)
{
// 加入的过滤接口
Type ChildType = item.GetType().GetProperty("type", flag).GetValue(item, null) as Type;
//如果表实现了该接口,则加入过滤
if (ChildType == type|| (ChildType.IsInterface&&type.GetInterfaces().Contains(ChildType)))
{
var entityInfo = db.EntityMaintenance.GetEntityInfo(ChildType);
var exp = field.GetValue(item, null) as Expression;
var whereStr = isWhere ? " AND " : " WHERE ";
isWhere = true;
result += (whereStr + SubTools.GetMethodValue(Context, exp, ResolveExpressType.WhereSingle));
}
}
}
}
}
return result;
}
所以 我们研究了一下,如何进行表字段过滤,顺便解决了一下心中疑惑,同时是不是自己也可以造轮子了呢。:)
总结 :实现了该过滤接口的表才会进行过滤,没有则不会。至于是如何实现可以看上面代码。