mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 02:32:50 +08:00
- 移除 IBaseRepository DataFilter 仓储过滤器;
This commit is contained in:
parent
e461e60113
commit
3e3fcf9580
@ -533,32 +533,6 @@
|
|||||||
<param name="asTable">分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository</param>
|
<param name="asTable">分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository</param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:FreeSql.IDataFilter`1.Enable(System.String[])">
|
|
||||||
<summary>
|
|
||||||
开启过滤器,若使用 using 则使用完后,恢复为原有状态
|
|
||||||
</summary>
|
|
||||||
<param name="filterName">过滤器名称</param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:FreeSql.IDataFilter`1.EnableAll">
|
|
||||||
<summary>
|
|
||||||
开启所有过滤器,若使用 using 则使用完后,恢复为原有状态
|
|
||||||
</summary>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:FreeSql.IDataFilter`1.Disable(System.String[])">
|
|
||||||
<summary>
|
|
||||||
禁用过滤器,若使用 using 则使用完后,恢复为原有状态
|
|
||||||
</summary>
|
|
||||||
<param name="filterName"></param>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:FreeSql.IDataFilter`1.DisableAll">
|
|
||||||
<summary>
|
|
||||||
禁用所有过滤器,若使用 using 则使用完后,恢复为原有状态
|
|
||||||
</summary>
|
|
||||||
<returns></returns>
|
|
||||||
</member>
|
|
||||||
<member name="M:FreeSql.IBaseRepository.AsType(System.Type)">
|
<member name="M:FreeSql.IBaseRepository.AsType(System.Type)">
|
||||||
<summary>
|
<summary>
|
||||||
动态Type,在使用 Repository<object> 后使用本方法,指定实体类型
|
动态Type,在使用 Repository<object> 后使用本方法,指定实体类型
|
||||||
@ -826,12 +800,11 @@
|
|||||||
<param name="that"></param>
|
<param name="that"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
|
<member name="M:Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Reflection.Assembly[])">
|
||||||
<summary>
|
<summary>
|
||||||
批量注入 Repository,可以参考代码自行调整
|
批量注入 Repository,可以参考代码自行调整
|
||||||
</summary>
|
</summary>
|
||||||
<param name="services"></param>
|
<param name="services"></param>
|
||||||
<param name="globalDataFilter"></param>
|
|
||||||
<param name="assemblies"></param>
|
<param name="assemblies"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
@ -37,10 +37,6 @@ namespace FreeSql
|
|||||||
GetRepositoryDbField(entityType, "_asTablePriv").SetValue(repo,
|
GetRepositoryDbField(entityType, "_asTablePriv").SetValue(repo,
|
||||||
_repo.GetType().GetField("_asTablePriv", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(_repo));
|
_repo.GetType().GetField("_asTablePriv", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(_repo));
|
||||||
//GetRepositoryDbField(_repo.EntityType, "_asTablePriv").GetValue(_repo));
|
//GetRepositoryDbField(_repo.EntityType, "_asTablePriv").GetValue(_repo));
|
||||||
|
|
||||||
if (typeof(IBaseRepository<>).MakeGenericType(_repo.EntityType).IsAssignableFrom(_repo.GetType()))
|
|
||||||
typeof(RepositoryDbContext).GetMethod("SetRepositoryDataFilter").MakeGenericMethod(_repo.EntityType)
|
|
||||||
.Invoke(null, new object[] { repo, _repo });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var sd = Activator.CreateInstance(typeof(RepositoryDbSet<>).MakeGenericType(entityType), repo) as IDbSet;
|
var sd = Activator.CreateInstance(typeof(RepositoryDbSet<>).MakeGenericType(entityType), repo) as IDbSet;
|
||||||
@ -49,16 +45,6 @@ namespace FreeSql
|
|||||||
return sd;
|
return sd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetRepositoryDataFilter<TEntity>(object repo, IBaseRepository<TEntity> baseRepo) where TEntity : class
|
|
||||||
{
|
|
||||||
var filter = baseRepo.DataFilter as DataFilter<TEntity>;
|
|
||||||
DataFilterUtil.SetRepositoryDataFilter(repo, fl =>
|
|
||||||
{
|
|
||||||
foreach (var f in filter._filters)
|
|
||||||
fl.Apply<TEntity>(f.Key, f.Value.Expression);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
int SaveChangesSuccess()
|
int SaveChangesSuccess()
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -32,11 +32,6 @@ namespace FreeSql
|
|||||||
{
|
{
|
||||||
var select = base.OrmSelect(dywhere);
|
var select = base.OrmSelect(dywhere);
|
||||||
if (_repo._asTablePriv != null) select.AsTable(_repo._asTablePriv);
|
if (_repo._asTablePriv != null) select.AsTable(_repo._asTablePriv);
|
||||||
var filters = (_repo.DataFilter as DataFilter<TEntity>)._filters;
|
|
||||||
foreach (var filter in filters.Where(a => a.Value.IsEnabled == true)) select.Where(filter.Value.Expression);
|
|
||||||
var disableFilter = filters.Where(a => a.Value.IsEnabled == false).Select(a => a.Key).ToList();
|
|
||||||
disableFilter.AddRange((_repo.DataFilter as DataFilter<TEntity>)._filtersByOrm.Where(a => a.Value.IsEnabled == false).Select(a => a.Key));
|
|
||||||
if (disableFilter.Any()) select.DisableGlobalFilter(disableFilter.ToArray());
|
|
||||||
return select;
|
return select;
|
||||||
}
|
}
|
||||||
internal ISelect<TEntity> OrmSelectInternal(object dywhere) => OrmSelect(dywhere);
|
internal ISelect<TEntity> OrmSelectInternal(object dywhere) => OrmSelect(dywhere);
|
||||||
@ -44,11 +39,6 @@ namespace FreeSql
|
|||||||
{
|
{
|
||||||
var update = base.OrmUpdate(entitys);
|
var update = base.OrmUpdate(entitys);
|
||||||
if (_repo._asTablePriv != null) update.AsTable(old => _repo._asTablePriv(_entityType, old));
|
if (_repo._asTablePriv != null) update.AsTable(old => _repo._asTablePriv(_entityType, old));
|
||||||
var filters = (_repo.DataFilter as DataFilter<TEntity>)._filters;
|
|
||||||
foreach (var filter in filters.Where(a => a.Value.IsEnabled == true)) update.Where(filter.Value.Expression);
|
|
||||||
var disableFilter = filters.Where(a => a.Value.IsEnabled == false).Select(a => a.Key).ToList();
|
|
||||||
disableFilter.AddRange((_repo.DataFilter as DataFilter<TEntity>)._filtersByOrm.Where(a => a.Value.IsEnabled == false).Select(a => a.Key));
|
|
||||||
if (disableFilter.Any()) update.DisableGlobalFilter(disableFilter.ToArray());
|
|
||||||
return update;
|
return update;
|
||||||
}
|
}
|
||||||
internal IUpdate<TEntity> OrmUpdateInternal(IEnumerable<TEntity> entitys) => OrmUpdate(entitys);
|
internal IUpdate<TEntity> OrmUpdateInternal(IEnumerable<TEntity> entitys) => OrmUpdate(entitys);
|
||||||
@ -56,11 +46,6 @@ namespace FreeSql
|
|||||||
{
|
{
|
||||||
var delete = base.OrmDelete(dywhere);
|
var delete = base.OrmDelete(dywhere);
|
||||||
if (_repo._asTablePriv != null) delete.AsTable(old => _repo._asTablePriv(_entityType, old));
|
if (_repo._asTablePriv != null) delete.AsTable(old => _repo._asTablePriv(_entityType, old));
|
||||||
var filters = (_repo.DataFilter as DataFilter<TEntity>)._filters;
|
|
||||||
foreach (var filter in filters.Where(a => a.Value.IsEnabled == true)) delete.Where(filter.Value.Expression);
|
|
||||||
var disableFilter = filters.Where(a => a.Value.IsEnabled == false).Select(a => a.Key).ToList();
|
|
||||||
disableFilter.AddRange((_repo.DataFilter as DataFilter<TEntity>)._filtersByOrm.Where(a => a.Value.IsEnabled == false).Select(a => a.Key));
|
|
||||||
if (disableFilter.Any()) delete.DisableGlobalFilter(disableFilter.ToArray());
|
|
||||||
return delete;
|
return delete;
|
||||||
}
|
}
|
||||||
internal IDelete<TEntity> OrmDeleteInternal(object dywhere) => OrmDelete(dywhere);
|
internal IDelete<TEntity> OrmDeleteInternal(object dywhere) => OrmDelete(dywhere);
|
||||||
@ -77,14 +62,6 @@ namespace FreeSql
|
|||||||
{
|
{
|
||||||
var insert = base.OrmInsert(entitys);
|
var insert = base.OrmInsert(entitys);
|
||||||
if (_repo._asTablePriv != null) insert.AsTable(old => _repo._asTablePriv(_entityType, old));
|
if (_repo._asTablePriv != null) insert.AsTable(old => _repo._asTablePriv(_entityType, old));
|
||||||
var filters = (_repo.DataFilter as DataFilter<TEntity>)._filters.Where(a => a.Value.IsEnabled == true);
|
|
||||||
foreach (var filter in filters)
|
|
||||||
{
|
|
||||||
if (entitys != null)
|
|
||||||
foreach (var entity in entitys)
|
|
||||||
if (filter.Value.ExpressionDelegate?.Invoke(entity) == false)
|
|
||||||
throw new Exception(DbContextStrings.InsertError_Filter(filter.Key, filter.Value.Expression, _db.OrmOriginal.GetEntityString(_entityType, entity)));
|
|
||||||
}
|
|
||||||
return insert;
|
return insert;
|
||||||
}
|
}
|
||||||
internal IInsert<TEntity> OrmInsertInternal(TEntity entity) => OrmInsert(entity);
|
internal IInsert<TEntity> OrmInsertInternal(TEntity entity) => OrmInsert(entity);
|
||||||
|
@ -1,278 +0,0 @@
|
|||||||
using FreeSql.Internal;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
|
|
||||||
namespace FreeSql
|
|
||||||
{
|
|
||||||
public interface IDataFilter<TEntity> : IDisposable where TEntity : class
|
|
||||||
{
|
|
||||||
|
|
||||||
IDataFilter<TEntity> Apply(string filterName, Expression<Func<TEntity, bool>> filterAndValidateExp);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开启过滤器,若使用 using 则使用完后,恢复为原有状态
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="filterName">过滤器名称</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
IDisposable Enable(params string[] filterName);
|
|
||||||
/// <summary>
|
|
||||||
/// 开启所有过滤器,若使用 using 则使用完后,恢复为原有状态
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
IDisposable EnableAll();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 禁用过滤器,若使用 using 则使用完后,恢复为原有状态
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="filterName"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
IDisposable Disable(params string[] filterName);
|
|
||||||
/// <summary>
|
|
||||||
/// 禁用所有过滤器,若使用 using 则使用完后,恢复为原有状态
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
IDisposable DisableAll();
|
|
||||||
|
|
||||||
bool IsEnabled(string filterName);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class DataFilter<TEntity> : IDataFilter<TEntity> where TEntity : class
|
|
||||||
{
|
|
||||||
|
|
||||||
internal class FilterItem
|
|
||||||
{
|
|
||||||
public Expression<Func<TEntity, bool>> Expression { get; set; }
|
|
||||||
Func<TEntity, bool> _expressionDelegate;
|
|
||||||
public Func<TEntity, bool> ExpressionDelegate => _expressionDelegate ?? (_expressionDelegate = Expression?.Compile());
|
|
||||||
public bool IsEnabled { get; set; }
|
|
||||||
}
|
|
||||||
internal class FilterItemByOrm
|
|
||||||
{
|
|
||||||
public GlobalFilter.Item Filter { get; set; }
|
|
||||||
public bool IsEnabled { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
internal ConcurrentDictionary<string, FilterItem> _filters = new ConcurrentDictionary<string, FilterItem>(StringComparer.CurrentCultureIgnoreCase);
|
|
||||||
internal ConcurrentDictionary<string, FilterItemByOrm> _filtersByOrm = new ConcurrentDictionary<string, FilterItemByOrm>(StringComparer.CurrentCultureIgnoreCase);
|
|
||||||
public IDataFilter<TEntity> Apply(string filterName, Expression<Func<TEntity, bool>> filterAndValidateExp)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (filterName == null)
|
|
||||||
throw new ArgumentNullException(nameof(filterName));
|
|
||||||
if (filterAndValidateExp == null) return this;
|
|
||||||
|
|
||||||
var filterItem = new FilterItem { Expression = filterAndValidateExp, IsEnabled = true };
|
|
||||||
_filters.AddOrUpdate(filterName, filterItem, (k, v) => filterItem);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IDisposable Disable(params string[] filterName)
|
|
||||||
{
|
|
||||||
if (filterName == null || filterName.Any() == false) return new UsingAny(() => { });
|
|
||||||
|
|
||||||
List<string> restore = new List<string>();
|
|
||||||
List<string> restoreByOrm = new List<string>();
|
|
||||||
foreach (var name in filterName)
|
|
||||||
{
|
|
||||||
if (_filters.TryGetValue(name, out var tryfi))
|
|
||||||
{
|
|
||||||
if (tryfi.IsEnabled)
|
|
||||||
{
|
|
||||||
restore.Add(name);
|
|
||||||
tryfi.IsEnabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_filtersByOrm.TryGetValue(name, out var tryfiByOrm))
|
|
||||||
{
|
|
||||||
if (tryfiByOrm.IsEnabled)
|
|
||||||
{
|
|
||||||
restoreByOrm.Add(name);
|
|
||||||
tryfiByOrm.IsEnabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new UsingAny(() =>
|
|
||||||
{
|
|
||||||
restore.ForEach(name =>
|
|
||||||
{
|
|
||||||
if (_filters.TryGetValue(name, out var tryfi) && tryfi.IsEnabled == false)
|
|
||||||
tryfi.IsEnabled = true;
|
|
||||||
});
|
|
||||||
restoreByOrm.ForEach(name =>
|
|
||||||
{
|
|
||||||
if (_filtersByOrm.TryGetValue(name, out var tryfiByOrm) && tryfiByOrm.IsEnabled == false)
|
|
||||||
tryfiByOrm.IsEnabled = true;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
public IDisposable DisableAll()
|
|
||||||
{
|
|
||||||
List<string> restore = new List<string>();
|
|
||||||
List<string> restoreByOrm = new List<string>();
|
|
||||||
foreach (var val in _filters)
|
|
||||||
{
|
|
||||||
if (val.Value.IsEnabled)
|
|
||||||
{
|
|
||||||
restore.Add(val.Key);
|
|
||||||
val.Value.IsEnabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach (var val in _filtersByOrm)
|
|
||||||
{
|
|
||||||
if (val.Value.IsEnabled)
|
|
||||||
{
|
|
||||||
restoreByOrm.Add(val.Key);
|
|
||||||
val.Value.IsEnabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new UsingAny(() =>
|
|
||||||
{
|
|
||||||
restore.ForEach(name =>
|
|
||||||
{
|
|
||||||
if (_filters.TryGetValue(name, out var tryfi) && tryfi.IsEnabled == false)
|
|
||||||
tryfi.IsEnabled = true;
|
|
||||||
});
|
|
||||||
restoreByOrm.ForEach(name =>
|
|
||||||
{
|
|
||||||
if (_filtersByOrm.TryGetValue(name, out var tryfiByOrm) && tryfiByOrm.IsEnabled == false)
|
|
||||||
tryfiByOrm.IsEnabled = true;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
class UsingAny : IDisposable
|
|
||||||
{
|
|
||||||
Action _ondis;
|
|
||||||
public UsingAny(Action ondis)
|
|
||||||
{
|
|
||||||
_ondis = ondis;
|
|
||||||
}
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
_ondis?.Invoke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IDisposable Enable(params string[] filterName)
|
|
||||||
{
|
|
||||||
if (filterName == null || filterName.Any() == false) return new UsingAny(() => { });
|
|
||||||
|
|
||||||
List<string> restore = new List<string>();
|
|
||||||
List<string> restoreByOrm = new List<string>();
|
|
||||||
foreach (var name in filterName)
|
|
||||||
{
|
|
||||||
if (_filters.TryGetValue(name, out var tryfi))
|
|
||||||
{
|
|
||||||
if (tryfi.IsEnabled == false)
|
|
||||||
{
|
|
||||||
restore.Add(name);
|
|
||||||
tryfi.IsEnabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_filtersByOrm.TryGetValue(name, out var tryfiByOrm))
|
|
||||||
{
|
|
||||||
if (tryfiByOrm.IsEnabled == false)
|
|
||||||
{
|
|
||||||
restoreByOrm.Add(name);
|
|
||||||
tryfiByOrm.IsEnabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new UsingAny(() =>
|
|
||||||
{
|
|
||||||
restore.ForEach(name =>
|
|
||||||
{
|
|
||||||
if (_filters.TryGetValue(name, out var tryfi) && tryfi.IsEnabled == true)
|
|
||||||
tryfi.IsEnabled = false;
|
|
||||||
});
|
|
||||||
restoreByOrm.ForEach(name =>
|
|
||||||
{
|
|
||||||
if (_filtersByOrm.TryGetValue(name, out var tryfiByOrm) && tryfiByOrm.IsEnabled == true)
|
|
||||||
tryfiByOrm.IsEnabled = false;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
public IDisposable EnableAll()
|
|
||||||
{
|
|
||||||
List<string> restore = new List<string>();
|
|
||||||
List<string> restoreByOrm = new List<string>();
|
|
||||||
foreach (var val in _filters)
|
|
||||||
{
|
|
||||||
if (val.Value.IsEnabled == false)
|
|
||||||
{
|
|
||||||
restore.Add(val.Key);
|
|
||||||
val.Value.IsEnabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach (var val in _filtersByOrm)
|
|
||||||
{
|
|
||||||
if (val.Value.IsEnabled == false)
|
|
||||||
{
|
|
||||||
restoreByOrm.Add(val.Key);
|
|
||||||
val.Value.IsEnabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new UsingAny(() =>
|
|
||||||
{
|
|
||||||
restore.ForEach(name =>
|
|
||||||
{
|
|
||||||
if (_filters.TryGetValue(name, out var tryfi) && tryfi.IsEnabled == true)
|
|
||||||
tryfi.IsEnabled = false;
|
|
||||||
});
|
|
||||||
restoreByOrm.ForEach(name =>
|
|
||||||
{
|
|
||||||
if (_filtersByOrm.TryGetValue(name, out var tryfiByOrm) && tryfiByOrm.IsEnabled == true)
|
|
||||||
tryfiByOrm.IsEnabled = false;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsEnabled(string filterName)
|
|
||||||
{
|
|
||||||
if (filterName == null) return false;
|
|
||||||
return _filters.TryGetValue(filterName, out var tryfi) ? tryfi.IsEnabled :
|
|
||||||
_filtersByOrm.TryGetValue(filterName, out var tryfiByOrm) ? tryfiByOrm.IsEnabled : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
~DataFilter() => this.Dispose();
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
_filters.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FluentDataFilter : IDisposable
|
|
||||||
{
|
|
||||||
internal class FilterInfo
|
|
||||||
{
|
|
||||||
public Type type { get; }
|
|
||||||
public string name { get; }
|
|
||||||
public LambdaExpression exp { get; }
|
|
||||||
public FilterInfo(Type type, string name, LambdaExpression exp)
|
|
||||||
{
|
|
||||||
this.type = type;
|
|
||||||
this.name = name;
|
|
||||||
this.exp = exp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
internal List<FilterInfo> _filters = new List<FilterInfo>();
|
|
||||||
|
|
||||||
public FluentDataFilter Apply<TEntity>(string filterName, Expression<Func<TEntity, bool>> filterAndValidateExp) where TEntity : class
|
|
||||||
{
|
|
||||||
if (filterName == null)
|
|
||||||
throw new ArgumentNullException(nameof(filterName));
|
|
||||||
if (filterAndValidateExp == null) return this;
|
|
||||||
|
|
||||||
_filters.Add(new FilterInfo(typeof(TEntity), filterName, filterAndValidateExp));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~FluentDataFilter() => this.Dispose();
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
_filters.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,104 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace FreeSql
|
|
||||||
{
|
|
||||||
|
|
||||||
internal class DataFilterUtil
|
|
||||||
{
|
|
||||||
|
|
||||||
internal static Action<FluentDataFilter> _globalDataFilter;
|
|
||||||
|
|
||||||
static ConcurrentDictionary<Type, Delegate> _dicSetRepositoryDataFilterApplyDataFilterFunc = new ConcurrentDictionary<Type, Delegate>();
|
|
||||||
static ConcurrentDictionary<Type, ConcurrentDictionary<string, bool>> _dicSetRepositoryDataFilterConvertFilterNotExists = new ConcurrentDictionary<Type, ConcurrentDictionary<string, bool>>();
|
|
||||||
internal static void SetRepositoryDataFilter(object repos, Action<FluentDataFilter> scopedDataFilter)
|
|
||||||
{
|
|
||||||
if (scopedDataFilter != null)
|
|
||||||
{
|
|
||||||
SetRepositoryDataFilter(repos, null);
|
|
||||||
}
|
|
||||||
if (scopedDataFilter == null)
|
|
||||||
{
|
|
||||||
scopedDataFilter = _globalDataFilter;
|
|
||||||
}
|
|
||||||
if (scopedDataFilter == null) return;
|
|
||||||
using (var globalFilter = new FluentDataFilter())
|
|
||||||
{
|
|
||||||
scopedDataFilter(globalFilter);
|
|
||||||
|
|
||||||
var type = repos.GetType();
|
|
||||||
Type entityType = (repos as IBaseRepository).EntityType;
|
|
||||||
if (entityType == null) throw new Exception(DbContextStrings.FailedSetFilter_NotBelongIRpository);
|
|
||||||
|
|
||||||
var notExists = _dicSetRepositoryDataFilterConvertFilterNotExists.GetOrAdd(type, t => new ConcurrentDictionary<string, bool>());
|
|
||||||
var newFilter = new Dictionary<string, LambdaExpression>();
|
|
||||||
foreach (var gf in globalFilter._filters)
|
|
||||||
{
|
|
||||||
if (notExists.ContainsKey(gf.name)) continue;
|
|
||||||
|
|
||||||
LambdaExpression newExp = null;
|
|
||||||
var filterParameter1 = Expression.Parameter(entityType, gf.exp.Parameters[0].Name);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
newExp = Expression.Lambda(
|
|
||||||
typeof(Func<,>).MakeGenericType(entityType, typeof(bool)),
|
|
||||||
new ReplaceVisitor().Modify(gf.exp.Body, filterParameter1),
|
|
||||||
filterParameter1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
notExists.TryAdd(gf.name, true); //防止第二次错误
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
newFilter.Add(gf.name, newExp);
|
|
||||||
}
|
|
||||||
if (newFilter.Any() == false) return;
|
|
||||||
|
|
||||||
var del = _dicSetRepositoryDataFilterApplyDataFilterFunc.GetOrAdd(type, t =>
|
|
||||||
{
|
|
||||||
var reposParameter = Expression.Parameter(type);
|
|
||||||
var nameParameter = Expression.Parameter(typeof(string));
|
|
||||||
var expressionParameter = Expression.Parameter(
|
|
||||||
typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(entityType, typeof(bool)))
|
|
||||||
);
|
|
||||||
return Expression.Lambda(
|
|
||||||
Expression.Block(
|
|
||||||
Expression.Call(reposParameter, type.GetMethod("ApplyDataFilter", BindingFlags.Instance | BindingFlags.NonPublic), nameParameter, expressionParameter)
|
|
||||||
),
|
|
||||||
new[] {
|
|
||||||
reposParameter, nameParameter, expressionParameter
|
|
||||||
}
|
|
||||||
).Compile();
|
|
||||||
});
|
|
||||||
foreach (var nf in newFilter)
|
|
||||||
{
|
|
||||||
del.DynamicInvoke(repos, nf.Key, nf.Value);
|
|
||||||
}
|
|
||||||
newFilter.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ReplaceVisitor : ExpressionVisitor
|
|
||||||
{
|
|
||||||
private ParameterExpression parameter;
|
|
||||||
|
|
||||||
public Expression Modify(Expression expression, ParameterExpression parameter)
|
|
||||||
{
|
|
||||||
this.parameter = parameter;
|
|
||||||
return Visit(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Expression VisitMember(MemberExpression node)
|
|
||||||
{
|
|
||||||
if (node.Expression?.NodeType == ExpressionType.Parameter)
|
|
||||||
return Expression.Property(parameter, node.Member.Name);
|
|
||||||
return base.VisitMember(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,18 +13,10 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||||||
/// 批量注入 Repository,可以参考代码自行调整
|
/// 批量注入 Repository,可以参考代码自行调整
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="services"></param>
|
/// <param name="services"></param>
|
||||||
/// <param name="globalDataFilter"></param>
|
|
||||||
/// <param name="assemblies"></param>
|
/// <param name="assemblies"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static IServiceCollection AddFreeRepository(this IServiceCollection services, Action<FluentDataFilter> globalDataFilter = null, params Assembly[] assemblies)
|
public static IServiceCollection AddFreeRepository(this IServiceCollection services, params Assembly[] assemblies)
|
||||||
{
|
{
|
||||||
if (globalDataFilter != null)
|
|
||||||
{
|
|
||||||
DataFilterUtil._globalDataFilter = globalDataFilter;
|
|
||||||
//如果看到了这里的代码,想自己调整,但因为 _globalDataFilter 是内部属性,无法修改?
|
|
||||||
//请考虑改用 fsql.GlobalFilter.Apply
|
|
||||||
}
|
|
||||||
|
|
||||||
services.AddScoped(typeof(IBaseRepository<>), typeof(GuidRepository<>));
|
services.AddScoped(typeof(IBaseRepository<>), typeof(GuidRepository<>));
|
||||||
services.AddScoped(typeof(BaseRepository<>), typeof(GuidRepository<>));
|
services.AddScoped(typeof(BaseRepository<>), typeof(GuidRepository<>));
|
||||||
|
|
||||||
|
@ -17,26 +17,12 @@ namespace FreeSql
|
|||||||
internal RepositoryDbSet<TEntity> _dbsetPriv;
|
internal RepositoryDbSet<TEntity> _dbsetPriv;
|
||||||
internal RepositoryDbSet<TEntity> _dbset => _dbsetPriv ?? (_dbsetPriv = _db.Set<TEntity>() as RepositoryDbSet<TEntity>);
|
internal RepositoryDbSet<TEntity> _dbset => _dbsetPriv ?? (_dbsetPriv = _db.Set<TEntity>() as RepositoryDbSet<TEntity>);
|
||||||
|
|
||||||
public IDataFilter<TEntity> DataFilter { get; } = new DataFilter<TEntity>();
|
|
||||||
internal Func<Type, string, string> _asTablePriv;
|
internal Func<Type, string, string> _asTablePriv;
|
||||||
|
|
||||||
protected void ApplyDataFilter(string name, Expression<Func<TEntity, bool>> exp) => DataFilter.Apply(name, exp);
|
|
||||||
|
|
||||||
protected BaseRepository(IFreeSql fsql, Expression<Func<TEntity, bool>> filter, Func<string, string> asTable = null)
|
protected BaseRepository(IFreeSql fsql, Expression<Func<TEntity, bool>> filter, Func<string, string> asTable = null)
|
||||||
{
|
{
|
||||||
_ormScoped = DbContextScopedFreeSql.Create(fsql, () => _db, () => UnitOfWork);
|
_ormScoped = DbContextScopedFreeSql.Create(fsql, () => _db, () => UnitOfWork);
|
||||||
DataFilterUtil.SetRepositoryDataFilter(this, null);
|
|
||||||
DataFilter.Apply("", filter);
|
|
||||||
AsTable(asTable);
|
AsTable(asTable);
|
||||||
|
|
||||||
fsql?.GlobalFilter?.GetAllFilters().ForEach(gf =>
|
|
||||||
{
|
|
||||||
(DataFilter as DataFilter<TEntity>)._filtersByOrm.TryAdd(gf.Name, new DataFilter<TEntity>.FilterItemByOrm
|
|
||||||
{
|
|
||||||
Filter = gf,
|
|
||||||
IsEnabled = true
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~BaseRepository() => this.Dispose();
|
~BaseRepository() => this.Dispose();
|
||||||
@ -48,7 +34,6 @@ namespace FreeSql
|
|||||||
{
|
{
|
||||||
_dbsetPriv?.Dispose();
|
_dbsetPriv?.Dispose();
|
||||||
_dbPriv?.Dispose();
|
_dbPriv?.Dispose();
|
||||||
this.DataFilter?.Dispose();
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,6 @@ namespace FreeSql
|
|||||||
public interface IBaseRepository<TEntity> : IBaseRepository
|
public interface IBaseRepository<TEntity> : IBaseRepository
|
||||||
where TEntity : class
|
where TEntity : class
|
||||||
{
|
{
|
||||||
IDataFilter<TEntity> DataFilter { get; }
|
|
||||||
ISelect<TEntity> Select { get; }
|
ISelect<TEntity> Select { get; }
|
||||||
|
|
||||||
ISelect<TEntity> Where(Expression<Func<TEntity, bool>> exp);
|
ISelect<TEntity> Where(Expression<Func<TEntity, bool>> exp);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user