mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 01:05:27 +08:00 
			
		
		
		
	- 移除 IBaseRepository DataFilter 仓储过滤器;
This commit is contained in:
		@@ -533,32 +533,6 @@
 | 
			
		||||
            <param name="asTable">分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository</param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </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)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            动态Type,在使用 Repository<object> 后使用本方法,指定实体类型
 | 
			
		||||
@@ -826,12 +800,11 @@
 | 
			
		||||
            <param name="that"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </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>
 | 
			
		||||
            批量注入 Repository,可以参考代码自行调整
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="services"></param>
 | 
			
		||||
            <param name="globalDataFilter"></param>
 | 
			
		||||
            <param name="assemblies"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
 
 | 
			
		||||
@@ -37,10 +37,6 @@ namespace FreeSql
 | 
			
		||||
                GetRepositoryDbField(entityType, "_asTablePriv").SetValue(repo,
 | 
			
		||||
                    _repo.GetType().GetField("_asTablePriv", BindingFlags.Instance | BindingFlags.NonPublic).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;
 | 
			
		||||
@@ -49,16 +45,6 @@ namespace FreeSql
 | 
			
		||||
            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 ret;
 | 
			
		||||
 
 | 
			
		||||
@@ -32,11 +32,6 @@ namespace FreeSql
 | 
			
		||||
        {
 | 
			
		||||
            var select = base.OrmSelect(dywhere);
 | 
			
		||||
            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;
 | 
			
		||||
        }
 | 
			
		||||
        internal ISelect<TEntity> OrmSelectInternal(object dywhere) => OrmSelect(dywhere);
 | 
			
		||||
@@ -44,11 +39,6 @@ namespace FreeSql
 | 
			
		||||
        {
 | 
			
		||||
            var update = base.OrmUpdate(entitys);
 | 
			
		||||
			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;
 | 
			
		||||
        }
 | 
			
		||||
        internal IUpdate<TEntity> OrmUpdateInternal(IEnumerable<TEntity> entitys) => OrmUpdate(entitys);
 | 
			
		||||
@@ -56,11 +46,6 @@ namespace FreeSql
 | 
			
		||||
        {
 | 
			
		||||
            var delete = base.OrmDelete(dywhere);
 | 
			
		||||
			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;
 | 
			
		||||
        }
 | 
			
		||||
        internal IDelete<TEntity> OrmDeleteInternal(object dywhere) => OrmDelete(dywhere);
 | 
			
		||||
@@ -77,14 +62,6 @@ namespace FreeSql
 | 
			
		||||
        {
 | 
			
		||||
            var insert = base.OrmInsert(entitys);
 | 
			
		||||
			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;
 | 
			
		||||
        }
 | 
			
		||||
        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,可以参考代码自行调整
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="services"></param>
 | 
			
		||||
        /// <param name="globalDataFilter"></param>
 | 
			
		||||
        /// <param name="assemblies"></param>
 | 
			
		||||
        /// <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(BaseRepository<>), typeof(GuidRepository<>));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,26 +17,12 @@ namespace FreeSql
 | 
			
		||||
        internal RepositoryDbSet<TEntity> _dbsetPriv;
 | 
			
		||||
        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;
 | 
			
		||||
 | 
			
		||||
        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)
 | 
			
		||||
        {
 | 
			
		||||
            _ormScoped = DbContextScopedFreeSql.Create(fsql, () => _db, () => UnitOfWork);
 | 
			
		||||
            DataFilterUtil.SetRepositoryDataFilter(this, null);
 | 
			
		||||
            DataFilter.Apply("", filter);
 | 
			
		||||
            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();
 | 
			
		||||
@@ -48,7 +34,6 @@ namespace FreeSql
 | 
			
		||||
            {
 | 
			
		||||
                _dbsetPriv?.Dispose();
 | 
			
		||||
                _dbPriv?.Dispose();
 | 
			
		||||
                this.DataFilter?.Dispose();
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,6 @@ namespace FreeSql
 | 
			
		||||
    public interface IBaseRepository<TEntity> : IBaseRepository
 | 
			
		||||
        where TEntity : class
 | 
			
		||||
    {
 | 
			
		||||
        IDataFilter<TEntity> DataFilter { get; }
 | 
			
		||||
        ISelect<TEntity> Select { get; }
 | 
			
		||||
 | 
			
		||||
        ISelect<TEntity> Where(Expression<Func<TEntity, bool>> exp);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user