From acf6fa0391b3f1394a78f0d76539863db8c617ff Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 12 Mar 2019 16:33:10 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E4=BF=AE=E6=94=B9=20FreeSql.Repository=20A?= =?UTF-8?q?utofac=20=E6=B3=A8=E5=85=A5=E6=96=B9=E5=BC=8F=EF=BC=8C=E7=9C=9F?= =?UTF-8?q?=E6=AD=A3=E7=9A=84=E5=AE=9E=E7=8E=B0=E5=85=A8=E5=B1=80=E8=BF=87?= =?UTF-8?q?=E6=BB=A4=E5=8A=9F=E8=83=BD=EF=BC=9B=20-=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=20FreeSql.Repository=20DataFilter=20=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=EF=BC=9B=20```csharp=20repos.DataFilter.Disable("test")=20?= =?UTF-8?q?=E4=B8=B4=E6=97=B6=E7=A6=81=E7=94=A8=EF=BC=8C=E4=B8=8D=E5=BD=B1?= =?UTF-8?q?=E5=93=8D=E5=85=A8=E9=83=A8=EF=BC=9B=20repos.DataFilter.Disable?= =?UTF-8?q?All()=20repos.DataFilter.Enable("test")=20repos.DataFilter.Enab?= =?UTF-8?q?leAll()=20repos.DataFilter.Apply("name",=20a=20=3D>=20a.Id=20>?= =?UTF-8?q?=201)=20=E9=99=84=E5=8A=A0=E6=96=B0=E7=9A=84=E8=BF=87=E6=BB=A4?= =?UTF-8?q?=E5=99=A8=20```?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/repository_01/Startup.cs | 5 +- FreeSql.Repository/BaseRepository.cs | 112 +++++++------ FreeSql.Repository/DataFilter.cs | 92 +++++++++++ .../Extenssions/AutofacExtenssions.cs | 147 +++++++----------- .../Extenssions/IFreeSqlExtenssions.cs | 7 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Repository/GuidRepository.cs | 14 +- FreeSql.Repository/IReadOnlyRepository.cs | 2 + FreeSql/FreeSql.csproj | 2 +- .../CommonProvider/AdoProvider/AdoProvider.cs | 4 + .../AdoProvider/AdoProviderAsync.cs | 4 + .../Internal/CommonProvider/CacheProvider.cs | 2 +- 12 files changed, 221 insertions(+), 172 deletions(-) create mode 100644 FreeSql.Repository/DataFilter.cs diff --git a/Examples/repository_01/Startup.cs b/Examples/repository_01/Startup.cs index 9a44a520..f8d2bfc3 100644 --- a/Examples/repository_01/Startup.cs +++ b/Examples/repository_01/Startup.cs @@ -67,8 +67,9 @@ namespace repository_01 { var builder = new ContainerBuilder(); - builder.RegisterFreeRepositoryAndFilter(() => a => a.Title == DateTime.Now.ToString() + System.Threading.Thread.CurrentThread.ManagedThreadId); - //builder.RegisterFreeGuidRepository(a => a.Id == 1, oldname => $"{oldname}_{DateTime.Now.Year}"); + builder.RegisterFreeRepository(filter => + filter.Apply("test", a => a.Title == DateTime.Now.ToString() + System.Threading.Thread.CurrentThread.ManagedThreadId) + ); builder.Populate(services); var container = builder.Build(); diff --git a/FreeSql.Repository/BaseRepository.cs b/FreeSql.Repository/BaseRepository.cs index d4f8e919..f98a57bd 100644 --- a/FreeSql.Repository/BaseRepository.cs +++ b/FreeSql.Repository/BaseRepository.cs @@ -9,18 +9,7 @@ namespace FreeSql { where TEntity : class { protected IFreeSql _fsql; - - Expression> _filterVal; - protected Expression> Filter { - get => _filterVal; - set { - _filterVal = value; - FilterCompile = value?.Compile(); - } - } - internal Expression> FilterInternal => Filter; - protected Func FilterCompile { get; private set; } - internal Func FilterCompileInternal => FilterCompile; + public IDataFilter DataFilter { get; } = new DataFilter(); Func _asTableVal; protected Func AsTable { @@ -36,35 +25,24 @@ namespace FreeSql { protected Type EntityType { get; } = typeof(TEntity); protected BaseRepository(IFreeSql fsql, Expression> filter, Func asTable = null) : base() { - _fsql = fsql ?? throw new NullReferenceException("fsql 参数不可为空"); - Filter = filter; + _fsql = fsql ?? throw new NullReferenceException(nameof(fsql)); + DataFilter.Apply("", filter); AsTable = asTable; } - public ISelect Select => _fsql.Select().Where(Filter).AsTable(AsTableSelect); + public ISelect Select => OrmSelect(null); + public IUpdate UpdateDiy => OrmUpdate(null); - public IUpdate UpdateDiy => _fsql.Update().Where(Filter).AsTable(AsTable); - - public int Delete(Expression> predicate) => _fsql.Delete().Where(Filter).Where(predicate).AsTable(AsTable).ExecuteAffrows(); - - public int Delete(TEntity entity) { - ValidatorEntityAndThrow(entity); - return _fsql.Delete(entity).Where(Filter).AsTable(AsTable).ExecuteAffrows(); - } - - public Task DeleteAsync(Expression> predicate) => _fsql.Delete().Where(Filter).Where(predicate).AsTable(AsTable).ExecuteAffrowsAsync(); - - public Task DeleteAsync(TEntity entity) { - ValidatorEntityAndThrow(entity); - return _fsql.Delete(entity).Where(Filter).AsTable(AsTable).ExecuteAffrowsAsync(); - } + public int Delete(Expression> predicate) => OrmDelete(null).Where(predicate).ExecuteAffrows(); + public int Delete(TEntity entity) => OrmDelete(entity).ExecuteAffrows(); + public Task DeleteAsync(Expression> predicate) => OrmDelete(null).Where(predicate).ExecuteAffrowsAsync(); + public Task DeleteAsync(TEntity entity) => OrmDelete(entity).ExecuteAffrowsAsync(); public virtual TEntity Insert(TEntity entity) { - ValidatorEntityAndThrow(entity); switch (_fsql.Ado.DataType) { case DataType.SqlServer: case DataType.PostgreSQL: - return _fsql.Insert().AppendData(entity).AsTable(AsTable).ExecuteInserted().FirstOrDefault(); + return OrmInsert(entity).ExecuteInserted().FirstOrDefault(); case DataType.MySql: case DataType.Oracle: case DataType.Sqlite: @@ -72,13 +50,11 @@ namespace FreeSql { throw new NotImplementedException($"{_fsql.Ado.DataType}不支持类似returning或output类型的特性,请参考FreeSql插入数据的方法重新实现。"); } } - public virtual List Insert(IEnumerable entitys) { - ValidatorEntityAndThrow(entitys); switch (_fsql.Ado.DataType) { case DataType.SqlServer: case DataType.PostgreSQL: - return _fsql.Insert().AppendData(entitys).AsTable(AsTable).ExecuteInserted(); + return OrmInsert(entitys).ExecuteInserted(); case DataType.MySql: case DataType.Oracle: case DataType.Sqlite: @@ -86,13 +62,11 @@ namespace FreeSql { throw new NotImplementedException($"{_fsql.Ado.DataType}不支持类似returning或output类型的特性,请参考FreeSql插入数据的方法重新实现。"); } } - async public virtual Task InsertAsync(TEntity entity) { - ValidatorEntityAndThrow(entity); switch (_fsql.Ado.DataType) { case DataType.SqlServer: case DataType.PostgreSQL: - return (await _fsql.Insert().AppendData(entity).AsTable(AsTable).ExecuteInsertedAsync()).FirstOrDefault(); + return (await OrmInsert(entity).ExecuteInsertedAsync()).FirstOrDefault(); case DataType.MySql: case DataType.Oracle: case DataType.Sqlite: @@ -100,13 +74,11 @@ namespace FreeSql { throw new NotImplementedException($"{_fsql.Ado.DataType}不支持类似returning或output类型的特性,请参考FreeSql插入数据的方法重新实现。"); } } - public virtual Task> InsertAsync(IEnumerable entitys) { - ValidatorEntityAndThrow(entitys); switch (_fsql.Ado.DataType) { case DataType.SqlServer: case DataType.PostgreSQL: - return _fsql.Insert().AppendData(entitys).AsTable(AsTable).ExecuteInsertedAsync(); + return OrmInsert(entitys).ExecuteInsertedAsync(); case DataType.MySql: case DataType.Oracle: case DataType.Sqlite: @@ -115,22 +87,45 @@ namespace FreeSql { } } - public int Update(TEntity entity) { - ValidatorEntityAndThrow(entity); - return _fsql.Update().SetSource(entity).Where(Filter).AsTable(AsTable).ExecuteAffrows(); - } + public int Update(TEntity entity) => OrmUpdate(entity).ExecuteAffrows(); + public Task UpdateAsync(TEntity entity) => OrmUpdate(entity).ExecuteAffrowsAsync(); - public Task UpdateAsync(TEntity entity) { - ValidatorEntityAndThrow(entity); - return _fsql.Update().SetSource(entity).Where(Filter).AsTable(AsTable).ExecuteAffrowsAsync(); + protected ISelect OrmSelect(object dywhere) { + var select = _fsql.Select(dywhere); + var filters = (DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + foreach (var filter in filters) select.Where(filter.Value.Expression); + return select.AsTable(AsTableSelect); } - - protected void ValidatorEntityAndThrow(TEntity entity) => ValidatorEntityAndThrow(new[] { entity }); - protected virtual void ValidatorEntityAndThrow(IEnumerable entitys) { - foreach (var entity in entitys) { - if (FilterCompile?.Invoke(entity) == false) throw new Exception($"FreeSql.Repository Insert 失败,因为设置了 {Filter},插入的数据不符合"); + protected IUpdate OrmUpdate(object dywhere) { + var entityObj = dywhere as TEntity; + var update = _fsql.Update(dywhere); + var filters = (DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + foreach (var filter in filters) { + if (entityObj != null && filter.Value.ExpressionDelegate?.Invoke(entityObj) == false) + throw new Exception($"FreeSql.Repository Update 失败,因为设置了 {filter.Key}: {filter.Value.Expression},更新的数据不符合"); + update.Where(filter.Value.Expression); } + return update.AsTable(AsTable); } + protected IDelete OrmDelete(object dywhere) { + var delete = _fsql.Delete(dywhere); + var filters = (DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + foreach (var filter in filters) delete.Where(filter.Value.Expression); + return delete.AsTable(AsTable); + } + protected IInsert OrmInsert(TEntity entity) => OrmInsert(new[] { entity }); + protected IInsert OrmInsert(IEnumerable entitys) { + var insert = _fsql.Insert(entitys); + var filters = (DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + foreach (var filter in filters) { + foreach (var entity in entitys) + if (entity != null && filter.Value.ExpressionDelegate?.Invoke(entity) == false) + throw new Exception($"FreeSql.Repository Insert 失败,因为设置了 {filter.Key}: {filter.Value.Expression},插入的数据不符合"); + } + return insert.AsTable(AsTable); + } + + protected void ApplyDataFilter(string name, Expression> exp) => DataFilter.Apply(name, exp); } public abstract class BaseRepository : BaseRepository, IRepository @@ -139,16 +134,13 @@ namespace FreeSql { public BaseRepository(IFreeSql fsql, Expression> filter, Func asTable = null) : base(fsql, filter, asTable) { } - public int Delete(TKey id) => _fsql.Delete(id).Where(Filter).AsTable(AsTable).ExecuteAffrows(); + public int Delete(TKey id) => OrmDelete(id).ExecuteAffrows(); + public Task DeleteAsync(TKey id) => OrmDelete(id).ExecuteAffrowsAsync(); - public Task DeleteAsync(TKey id) => _fsql.Delete(id).Where(Filter).AsTable(AsTable).ExecuteAffrowsAsync(); - - public TEntity Find(TKey id) => _fsql.Select(id).Where(Filter).AsTable(AsTableSelect).ToOne(); - - public Task FindAsync(TKey id) => _fsql.Select(id).Where(Filter).AsTable(AsTableSelect).ToOneAsync(); + public TEntity Find(TKey id) => OrmSelect(id).ToOne(); + public Task FindAsync(TKey id) => OrmSelect(id).ToOneAsync(); public TEntity Get(TKey id) => Find(id); - public Task GetAsync(TKey id) => FindAsync(id); } } diff --git a/FreeSql.Repository/DataFilter.cs b/FreeSql.Repository/DataFilter.cs new file mode 100644 index 00000000..2ad442a0 --- /dev/null +++ b/FreeSql.Repository/DataFilter.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Linq.Expressions; +using System.Text; +using System.Linq; + +namespace FreeSql { + public interface IDataFilter where TEntity : class { + + IDataFilter Apply(string filterName, Expression> filterAndValidateExp); + + IDataFilter Enable(params string[] filterName); + IDataFilter EnableAll(); + + IDataFilter Disable(params string[] filterName); + IDataFilter DisableAll(); + + bool IsEnabled(string filterName); + } + + internal class DataFilter : IDataFilter where TEntity : class { + + internal class FilterItem { + public Expression> Expression { get; set; } + Func _expressionDelegate; + public Func ExpressionDelegate => _expressionDelegate ?? (_expressionDelegate = Expression?.Compile()); + public bool IsEnabled { get; set; } + } + + internal ConcurrentDictionary _filters = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + public IDataFilter Apply(string filterName, Expression> 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 IDataFilter Disable(params string[] filterName) { + if (filterName == null || filterName.Any() == false) return this; + + foreach (var name in filterName) { + if (_filters.TryGetValue(name, out var tryfi)) + tryfi.IsEnabled = false; + } + return this; + } + public IDataFilter DisableAll() { + foreach (var val in _filters.Values.ToArray()) + val.IsEnabled = false; + return this; + } + + public IDataFilter Enable(params string[] filterName) { + if (filterName == null || filterName.Any() == false) return this; + + foreach (var name in filterName) { + if (_filters.TryGetValue(name, out var tryfi)) + tryfi.IsEnabled = true; + } + return this; + } + public IDataFilter EnableAll() { + foreach (var val in _filters.Values.ToArray()) + val.IsEnabled = true; + return this; + } + + public bool IsEnabled(string filterName) { + if (filterName == null) return false; + return _filters.TryGetValue(filterName, out var tryfi) ? tryfi.IsEnabled : false; + } + } + + public class GlobalDataFilter { + + internal List<(Type type, string name, LambdaExpression exp)> _filters = new List<(Type type, string name, LambdaExpression exp)>(); + + public GlobalDataFilter Apply(string filterName, Expression> filterAndValidateExp) where TEntity : class { + if (filterName == null) + throw new ArgumentNullException(nameof(filterName)); + if (filterAndValidateExp == null) return this; + + _filters.Add((typeof(TEntity), filterName, filterAndValidateExp)); + return this; + } + } +} diff --git a/FreeSql.Repository/Extenssions/AutofacExtenssions.cs b/FreeSql.Repository/Extenssions/AutofacExtenssions.cs index cecfeafc..6a079902 100644 --- a/FreeSql.Repository/Extenssions/AutofacExtenssions.cs +++ b/FreeSql.Repository/Extenssions/AutofacExtenssions.cs @@ -5,41 +5,62 @@ using System.Collections.Generic; using System.Collections.Concurrent; using System.Linq.Expressions; using System.Reflection; +using System.Linq; public static class FreeSqlRepositoryAutofacExtenssions { - public static void RegisterFreeRepository(this ContainerBuilder builder) => RegisterFreeRepositoryPrivate(builder, null, null); - public static void RegisterFreeRepositoryAndFilter(this ContainerBuilder builder, Func>> filterHandler) => RegisterFreeRepositoryPrivate(builder, filterHandler, null); + public static void RegisterFreeRepository(this ContainerBuilder builder, Action globalDataFilter) => RegisterFreeRepositoryPrivate(builder, globalDataFilter); - static ConcurrentDictionary _dicRegisterFreeRepositorySetFilterFunc = new ConcurrentDictionary(); - static ConcurrentDictionary _dicRegisterFreeRepositorySetAsTableFunc = new ConcurrentDictionary(); - static void RegisterFreeRepositoryPrivate(ContainerBuilder builder, Func>> filterHandler, Func asTableHandler) { + static ConcurrentDictionary _dicRegisterFreeRepositoryPrivateSetFilterFunc = new ConcurrentDictionary(); + static ConcurrentDictionary> _dicRegisterFreeRepositoryPrivateConvertFilterNotExists = new ConcurrentDictionary>(); + static void RegisterFreeRepositoryPrivate(ContainerBuilder builder, Action globalDataFilter) { - Func setFilterFunc = reposType => _dicRegisterFreeRepositorySetFilterFunc.GetOrAdd(reposType, type => { - var reposParameter = Expression.Parameter(type); - var fitlerParameter = Expression.Parameter(typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(type.GenericTypeArguments[0], typeof(bool)))); - return Expression.Lambda( - Expression.Block( - Expression.Call(reposParameter, type.GetMethod("set_Filter", BindingFlags.Instance | BindingFlags.NonPublic), fitlerParameter) - ), - new[] { - reposParameter, fitlerParameter - } - ).Compile(); - }); - Func convertFilter = type => { - var filter = filterHandler?.Invoke(); - if (filter == null) return null; + Action funcSetDataFilter = instance => { + if (globalDataFilter == null) return; + var globalFilter = new GlobalDataFilter(); + globalDataFilter(globalFilter); + + var type = instance.GetType(); var entityType = type.GenericTypeArguments[0]; - var filterParameter1 = Expression.Parameter(entityType, filter.Parameters[0].Name); - try { - return Expression.Lambda( - typeof(Func<,>).MakeGenericType(entityType, typeof(bool)), - new ReplaceVisitor().Modify(filter.Body, filterParameter1), - filterParameter1 + + var notExists = _dicRegisterFreeRepositoryPrivateConvertFilterNotExists.GetOrAdd(type, t => new ConcurrentDictionary()); + var newFilter = new Dictionary(); + 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, gf.exp); + } + if (newFilter.Any() == false) return; + + var del = _dicRegisterFreeRepositoryPrivateSetFilterFunc.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))) ); - } catch { - return null; + 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(instance, nf.Key, nf.Value); } }; @@ -49,10 +70,7 @@ public static class FreeSqlRepositoryAutofacExtenssions { typeof(IBasicRepository<>), typeof(IReadOnlyRepository<>) ).OnActivating(a => { - if (filterHandler != null) { - var type = a.Instance.GetType(); - setFilterFunc(type)?.DynamicInvoke(a.Instance, convertFilter(type)); - } + funcSetDataFilter(a.Instance); }).InstancePerDependency(); builder.RegisterGeneric(typeof(DefaultRepository<,>)).As( @@ -61,72 +79,11 @@ public static class FreeSqlRepositoryAutofacExtenssions { typeof(IBasicRepository<,>), typeof(IReadOnlyRepository<,>) ).OnActivating(a => { - if (filterHandler != null) { - var type = a.Instance.GetType(); - setFilterFunc(type)?.DynamicInvoke(a.Instance, convertFilter(type)); - } + funcSetDataFilter(a.Instance); }).InstancePerDependency(); } - //static void RegisterRepository(this ContainerBuilder builder, Expression> filter, Func asTable, int regType) { - - // Func reposFunc = type => { - // var entityType = type.GenericTypeArguments[0]; - // var filterParameter1 = Expression.Parameter(entityType, filter.Parameters[0].Name); - // var convertFilter = Expression.Lambda( - // typeof(Func<,>).MakeGenericType(entityType, typeof(bool)), - // new ReplaceVisitor().Modify(filter.Body, filterParameter1), - // filterParameter1 - // ); - // var repos = Expression.Parameter(type); - // var blocks = new List(); - // if (filter != null) blocks.Add(Expression.Call(repos, type.GetMethod("set_Filter", BindingFlags.Instance | BindingFlags.NonPublic), Expression.Constant(convertFilter))); - // if (asTable != null) blocks.Add(Expression.Call(repos, type.GetMethod("set_AsTable", BindingFlags.Instance | BindingFlags.NonPublic), Expression.Constant(asTable))); - // return Expression.Lambda( - // //Expression.New( - // // typeof(GuidRepository<>).MakeGenericType(type.GenericTypeArguments).GetConstructors()[1], - // // Expression.Constant(a.Context.Resolve()), - // // Expression.Constant(convertFilter), - // // Expression.Constant(asTable) - // //) - // Expression.Block(blocks), - // repos - // ); - // }; - - // if (regType == 1) - // builder.RegisterGeneric(typeof(GuidRepository<>)).As( - // typeof(GuidRepository<>), - // typeof(BaseRepository<>), typeof(BaseRepository<,>), - // typeof(IBasicRepository<>), typeof(IBasicRepository<,>), - // typeof(IReadOnlyRepository<>), typeof(IReadOnlyRepository<,>) - // ).OnActivating(a => { - // if (filter != null) - // _dicAddGuidRepositoryFunc.GetOrAdd(a.Instance.GetType(), t => { - // try { reposFunc(t).Compile(); } catch { } - // return null; - // })?.DynamicInvoke(a.Instance); - // }).InstancePerDependency(); - - - // if (regType == 2) - // builder.RegisterGeneric(typeof(DefaultRepository<,>)).As( - // typeof(DefaultRepository<,>), - // typeof(BaseRepository<,>), - // typeof(IBasicRepository<,>), - // typeof(IReadOnlyRepository<,>) - // ).OnActivating(a => { - // if (filter != null) - // _dicAddGuidRepositoryFunc.GetOrAdd(a.Instance.GetType(), t => { - // try { reposFunc(t).Compile(); } catch { } - // return null; - // })?.DynamicInvoke(a.Instance); - // }).InstancePerDependency(); - //} - - //static ConcurrentDictionary _dicAddGuidRepositoryFunc = new ConcurrentDictionary(); - - class ReplaceVisitor : ExpressionVisitor { + class ReplaceVisitor : ExpressionVisitor { private ParameterExpression parameter; public Expression Modify(Expression expression, ParameterExpression parameter) { diff --git a/FreeSql.Repository/Extenssions/IFreeSqlExtenssions.cs b/FreeSql.Repository/Extenssions/IFreeSqlExtenssions.cs index 4073a702..3413b8ef 100644 --- a/FreeSql.Repository/Extenssions/IFreeSqlExtenssions.cs +++ b/FreeSql.Repository/Extenssions/IFreeSqlExtenssions.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Collections.Concurrent; using System.Text; using System.Linq.Expressions; +using System.Linq; public static class FreeSqlRepositoryIFreeSqlExtenssions { @@ -44,7 +45,7 @@ public static class FreeSqlRepositoryIFreeSqlExtenssions { static ConcurrentDictionary dicGetGuidRepository = new ConcurrentDictionary(); /// - /// 合并两个仓储的设置,以便查询 + /// 合并两个仓储的设置(过滤+分表),以便查询 /// /// /// @@ -52,6 +53,8 @@ public static class FreeSqlRepositoryIFreeSqlExtenssions { /// /// public static ISelect FromRepository(this ISelect that, BaseRepository repos) where TEntity : class where T2 : class { - return that.AsTable(repos.AsTableSelectInternal).Where(repos.FilterInternal); + var filters = (repos.DataFilter as DataFilter)._filters.Where(a => a.Value.IsEnabled == true); + foreach (var filter in filters) that.Where(filter.Value.Expression); + return that.AsTable(repos.AsTableSelectInternal); } } \ No newline at end of file diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 95844bb3..1a8905ec 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.3.12 + 0.3.13 YeXiangQin FreeSql 通用仓库层实现,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite,读写分离、分表分库。 https://github.com/2881099/FreeSql diff --git a/FreeSql.Repository/GuidRepository.cs b/FreeSql.Repository/GuidRepository.cs index 1ead9a92..cce6ba7f 100644 --- a/FreeSql.Repository/GuidRepository.cs +++ b/FreeSql.Repository/GuidRepository.cs @@ -17,26 +17,20 @@ namespace FreeSql { } public override List Insert(IEnumerable entity) { - base.ValidatorEntityAndThrow(entity); - _fsql.Insert().AppendData(entity).AsTable(AsTable).ExecuteAffrows(); + OrmInsert(entity).ExecuteAffrows(); return entity.ToList(); } - async public override Task> InsertAsync(IEnumerable entity) { - base.ValidatorEntityAndThrow(entity); - await _fsql.Insert().AppendData(entity).AsTable(AsTable).ExecuteAffrowsAsync(); + await OrmInsert(entity).ExecuteAffrowsAsync(); return entity.ToList(); } public override TEntity Insert(TEntity entity) { - base.ValidatorEntityAndThrow(entity); - _fsql.Insert().AppendData(entity).AsTable(AsTable).ExecuteAffrows(); + OrmInsert(entity).ExecuteAffrows(); return entity; } - async public override Task InsertAsync(TEntity entity) { - base.ValidatorEntityAndThrow(entity); - await _fsql.Insert().AppendData(entity).AsTable(AsTable).ExecuteAffrowsAsync(); + await OrmInsert(entity).ExecuteAffrowsAsync(); return entity; } } diff --git a/FreeSql.Repository/IReadOnlyRepository.cs b/FreeSql.Repository/IReadOnlyRepository.cs index ce3a9588..8ab03c03 100644 --- a/FreeSql.Repository/IReadOnlyRepository.cs +++ b/FreeSql.Repository/IReadOnlyRepository.cs @@ -4,6 +4,8 @@ namespace FreeSql { public interface IReadOnlyRepository : IRepository where TEntity : class { + IDataFilter DataFilter { get; } + ISelect Select { get; } } diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 3c35d0aa..c26e6b82 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.3.12 + 0.3.13 true YeXiangQin 打造 .NETCore 最方便的 ORM,DbFirst 与 CodeFirst 混合使用,提供从实体同步数据库,或者从数据库生成实体代码,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite,读写分离、分表分库。 diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index ed5020ef..1f6007bd 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -78,6 +78,7 @@ namespace FreeSql.Internal.CommonProvider { public List Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => Query(null, cmdType, cmdText, cmdParms); public List Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var ret = new List(); + if (string.IsNullOrEmpty(cmdText)) return ret; var type = typeof(T); int[] indexes = null; var props = dicQueryTypeGetProperties.GetOrAdd(type, k => type.GetProperties()); @@ -96,6 +97,7 @@ namespace FreeSql.Internal.CommonProvider { public void ExecuteReader(DbTransaction transaction, Action readerHander, string cmdText, object parms = null) => ExecuteReader(transaction, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public void ExecuteReader(Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReader(null, readerHander, cmdType, cmdText, cmdParms); public void ExecuteReader(DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { + if (string.IsNullOrEmpty(cmdText)) return; var dt = DateTime.Now; var logtxt = new StringBuilder(); var logtxt_dt = DateTime.Now; @@ -218,6 +220,7 @@ namespace FreeSql.Internal.CommonProvider { public int ExecuteNonQuery(DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQuery(transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQuery(null, cmdType, cmdText, cmdParms); public int ExecuteNonQuery(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { + if (string.IsNullOrEmpty(cmdText)) return 0; var dt = DateTime.Now; var logtxt = new StringBuilder(); var logtxt_dt = DateTime.Now; @@ -245,6 +248,7 @@ namespace FreeSql.Internal.CommonProvider { public object ExecuteScalar(DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalar(transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalar(null, cmdType, cmdText, cmdParms); public object ExecuteScalar(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { + if (string.IsNullOrEmpty(cmdText)) return null; var dt = DateTime.Now; var logtxt = new StringBuilder(); var logtxt_dt = DateTime.Now; diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index ad66ae30..9f5b8d70 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -14,6 +14,7 @@ namespace FreeSql.Internal.CommonProvider { public Task> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => QueryAsync(null, cmdType, cmdText, cmdParms); async public Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var ret = new List(); + if (string.IsNullOrEmpty(cmdText)) return ret; var type = typeof(T); int[] indexes = null; var props = dicQueryTypeGetProperties.GetOrAdd(type, k => type.GetProperties()); @@ -33,6 +34,7 @@ namespace FreeSql.Internal.CommonProvider { public Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, string cmdText, object parms = null) => ExecuteReaderAsync(transaction, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public Task ExecuteReaderAsync(Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteReaderAsync(null, readerHander, cmdType, cmdText, cmdParms); async public Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { + if (string.IsNullOrEmpty(cmdText)) return; var dt = DateTime.Now; var logtxt = new StringBuilder(); var logtxt_dt = DateTime.Now; @@ -155,6 +157,7 @@ namespace FreeSql.Internal.CommonProvider { public Task ExecuteNonQueryAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteNonQueryAsync(transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public Task ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteNonQueryAsync(null, cmdType, cmdText, cmdParms); async public Task ExecuteNonQueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { + if (string.IsNullOrEmpty(cmdText)) return 0; var dt = DateTime.Now; var logtxt = new StringBuilder(); var logtxt_dt = DateTime.Now; @@ -182,6 +185,7 @@ namespace FreeSql.Internal.CommonProvider { public Task ExecuteScalarAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteScalarAsync(transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); public Task ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteScalarAsync(null, cmdType, cmdText, cmdParms); async public Task ExecuteScalarAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { + if (string.IsNullOrEmpty(cmdText)) return null; var dt = DateTime.Now; var logtxt = new StringBuilder(); var logtxt_dt = DateTime.Now; diff --git a/FreeSql/Internal/CommonProvider/CacheProvider.cs b/FreeSql/Internal/CommonProvider/CacheProvider.cs index e8c2260d..5bc0e9d1 100644 --- a/FreeSql/Internal/CommonProvider/CacheProvider.cs +++ b/FreeSql/Internal/CommonProvider/CacheProvider.cs @@ -25,7 +25,7 @@ namespace FreeSql.Internal.CommonProvider { try { Cache.Remove($"{key1}|{key2}"); } catch { } // redis-cluster 不允许执行 multi keys 命令 CacheSupportMultiRemove = Cache.Get(key1) == null && cache.Get(key2) == null; if (CacheSupportMultiRemove == false) { - log.LogWarning("FreeSql Warning: 低性能, IDistributedCache 没实现批量删除缓存 Cache.Remove(\"key1|key2\")."); + //log.LogWarning("FreeSql Warning: 低性能, IDistributedCache 没实现批量删除缓存 Cache.Remove(\"key1|key2\")."); Remove(key1, key2); } }