From 30385d2e9168f0a87fbb65eeb16a00ad8f248c84 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 2 Mar 2019 20:46:26 +0800 Subject: [PATCH] =?UTF-8?q?-=20FreeSql.Repository=20=E5=A2=9E=E5=8A=A0=20f?= =?UTF-8?q?ilter=20=E5=8F=82=E6=95=B0=EF=BC=8C=E7=8E=B0=E5=AE=9E=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E8=BF=87=E6=BB=A4=20+=20=E9=AA=8C=E8=AF=81=EF=BC=9B?= =?UTF-8?q?=20=20=20=20=20=E5=A6=82=EF=BC=9Avar=20postRepos=20=3D=20fsql.G?= =?UTF-8?q?etGuidRepository(a=20=3D>=20a.TopicId=20=3D=3D=201);=20po?= =?UTF-8?q?stRepos=20CURD=20=E6=96=B9=E6=B3=95=E9=83=BD=E4=BC=9A=E4=BB=A5?= =?UTF-8?q?=20lambad=20=E6=9D=A1=E4=BB=B6=E4=BD=9C=E4=B8=BA=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E6=88=96=E9=AA=8C=E8=AF=81=EF=BC=8CUpdate/Insert?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E9=94=99=E8=AF=AF=E6=97=B6=E4=BC=9A=E6=8A=9B?= =?UTF-8?q?=E5=87=BA=E5=BC=82=E5=B8=B8=E3=80=82=20-=20ISelect=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=20First/FirstAsync=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.Repository/BaseRepository.cs | 66 +++++++++++++------ FreeSql.Repository/DefaultRepository.cs | 3 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql.Repository/GuidRepository.cs | 3 +- FreeSql.Repository/IBasicRepository.cs | 4 +- FreeSql.Repository/IFreeSqlExtenssions.cs | 25 +++++-- FreeSql/FreeSql.csproj | 2 +- FreeSql/Interface/Curd/ISelect/ISelect0.cs | 7 ++ FreeSql/Internal/CommonExpression.cs | 1 + .../SelectProvider/Select0Provider.cs | 5 +- 10 files changed, 84 insertions(+), 34 deletions(-) diff --git a/FreeSql.Repository/BaseRepository.cs b/FreeSql.Repository/BaseRepository.cs index de5fd837..75404ca5 100644 --- a/FreeSql.Repository/BaseRepository.cs +++ b/FreeSql.Repository/BaseRepository.cs @@ -9,25 +9,35 @@ namespace FreeSql { where TEntity : class { protected IFreeSql _fsql; + protected Expression> _filter; + protected Func _filterCompile; - public BaseRepository(IFreeSql fsql) : base() { - _fsql = fsql; - if (_fsql == null) throw new NullReferenceException("fsql 参数不可为空"); + public BaseRepository(IFreeSql fsql, Expression> filter) : base() { + _fsql = fsql ?? throw new NullReferenceException("fsql 参数不可为空"); + _filter = filter; + _filterCompile = filter?.Compile(); } - public ISelect Select => _fsql.Select(); + public ISelect Select => _fsql.Select().Where(_filter); - public IUpdate UpdateDiy => _fsql.Update(); + public IUpdate UpdateDiy => _fsql.Update().Where(_filter); - public int Delete(Expression> predicate) => _fsql.Delete().Where(predicate).ExecuteAffrows(); + public int Delete(Expression> predicate) => _fsql.Delete().Where(_filter).Where(predicate).ExecuteAffrows(); - public int Delete(TEntity entity) => _fsql.Delete(entity).ExecuteAffrows(); + public int Delete(TEntity entity) { + ValidatorEntityAndThrow(entity); + return _fsql.Delete(entity).Where(_filter).ExecuteAffrows(); + } - public Task DeleteAsync(Expression> predicate) => _fsql.Delete().Where(predicate).ExecuteAffrowsAsync(); + public Task DeleteAsync(Expression> predicate) => _fsql.Delete().Where(_filter).Where(predicate).ExecuteAffrowsAsync(); - public Task DeleteAsync(TEntity entity) => _fsql.Delete(entity).ExecuteAffrowsAsync(); + public Task DeleteAsync(TEntity entity) { + ValidatorEntityAndThrow(entity); + return _fsql.Delete(entity).Where(_filter).ExecuteAffrowsAsync(); + } public virtual TEntity Insert(TEntity entity) { + ValidatorEntityAndThrow(entity); switch (_fsql.Ado.DataType) { case DataType.SqlServer: case DataType.PostgreSQL: @@ -40,11 +50,12 @@ namespace FreeSql { } } - public virtual List Insert(IEnumerable entity) { + public virtual List Insert(IEnumerable entitys) { + ValidatorEntityAndThrow(entitys); switch (_fsql.Ado.DataType) { case DataType.SqlServer: case DataType.PostgreSQL: - return _fsql.Insert().AppendData(entity).ExecuteInserted(); + return _fsql.Insert().AppendData(entitys).ExecuteInserted(); case DataType.MySql: case DataType.Oracle: case DataType.Sqlite: @@ -54,6 +65,7 @@ namespace FreeSql { } async public virtual Task InsertAsync(TEntity entity) { + ValidatorEntityAndThrow(entity); switch (_fsql.Ado.DataType) { case DataType.SqlServer: case DataType.PostgreSQL: @@ -66,11 +78,12 @@ namespace FreeSql { } } - public virtual Task> InsertAsync(IEnumerable entity) { + public virtual Task> InsertAsync(IEnumerable entitys) { + ValidatorEntityAndThrow(entitys); switch (_fsql.Ado.DataType) { case DataType.SqlServer: case DataType.PostgreSQL: - return _fsql.Insert().AppendData(entity).ExecuteInsertedAsync(); + return _fsql.Insert().AppendData(entitys).ExecuteInsertedAsync(); case DataType.MySql: case DataType.Oracle: case DataType.Sqlite: @@ -79,24 +92,37 @@ namespace FreeSql { } } - public int Update(TEntity entity) => _fsql.Update().SetSource(entity).ExecuteAffrows(); + public int Update(TEntity entity) { + ValidatorEntityAndThrow(entity); + return _fsql.Update().SetSource(entity).Where(_filter).ExecuteAffrows(); + } - public Task UpdateAsync(TEntity entity) => _fsql.Update().SetSource(entity).ExecuteAffrowsAsync(); + public Task UpdateAsync(TEntity entity) { + ValidatorEntityAndThrow(entity); + return _fsql.Update().SetSource(entity).Where(_filter).ExecuteAffrowsAsync(); + } + + 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},插入的数据不符合"); + } + } } public abstract class BaseRepository : BaseRepository, IRepository where TEntity : class { - public BaseRepository(IFreeSql fsql) : base(fsql) { + public BaseRepository(IFreeSql fsql, Expression> filter) : base(fsql, filter) { } - public int Delete(TKey id) => _fsql.Delete(id).ExecuteAffrows(); + public int Delete(TKey id) => _fsql.Delete(id).Where(_filter).ExecuteAffrows(); - public Task DeleteAsync(TKey id) => _fsql.Delete(id).ExecuteAffrowsAsync(); + public Task DeleteAsync(TKey id) => _fsql.Delete(id).Where(_filter).ExecuteAffrowsAsync(); - public TEntity Find(TKey id) => _fsql.Select(id).ToOne(); + public TEntity Find(TKey id) => _fsql.Select(id).Where(_filter).ToOne(); - public Task FindAsync(TKey id) => _fsql.Select(id).ToOneAsync(); + public Task FindAsync(TKey id) => _fsql.Select(id).Where(_filter).ToOneAsync(); public TEntity Get(TKey id) => Find(id); diff --git a/FreeSql.Repository/DefaultRepository.cs b/FreeSql.Repository/DefaultRepository.cs index 092bdffc..8ba7c071 100644 --- a/FreeSql.Repository/DefaultRepository.cs +++ b/FreeSql.Repository/DefaultRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; @@ -8,7 +9,7 @@ namespace FreeSql { BaseRepository where TEntity : class { - public DefaultRepository(IFreeSql fsql) : base(fsql) { + public DefaultRepository(IFreeSql fsql, Expression> filter) : base(fsql, filter) { } } } diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index af723004..ec05f3d8 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.1.6 + 0.1.7 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 e2e30ebd..40b7c1ce 100644 --- a/FreeSql.Repository/GuidRepository.cs +++ b/FreeSql.Repository/GuidRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; @@ -9,7 +10,7 @@ namespace FreeSql { BaseRepository where TEntity : class { - public GuidRepository(IFreeSql fsql) : base(fsql) { + public GuidRepository(IFreeSql fsql, Expression> filter) : base(fsql, filter) { } public override List Insert(IEnumerable entity) { diff --git a/FreeSql.Repository/IBasicRepository.cs b/FreeSql.Repository/IBasicRepository.cs index 63db1f7c..a86404c0 100644 --- a/FreeSql.Repository/IBasicRepository.cs +++ b/FreeSql.Repository/IBasicRepository.cs @@ -6,11 +6,11 @@ namespace FreeSql { where TEntity : class { TEntity Insert(TEntity entity); - List Insert(IEnumerable entity); + List Insert(IEnumerable entitys); Task InsertAsync(TEntity entity); - Task> InsertAsync(IEnumerable entity); + Task> InsertAsync(IEnumerable entitys); int Update(TEntity entity); diff --git a/FreeSql.Repository/IFreeSqlExtenssions.cs b/FreeSql.Repository/IFreeSqlExtenssions.cs index 36edc276..84246ad5 100644 --- a/FreeSql.Repository/IFreeSqlExtenssions.cs +++ b/FreeSql.Repository/IFreeSqlExtenssions.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Collections.Concurrent; using System.Text; +using System.Linq.Expressions; public static class IFreeSqlExtenssions { @@ -12,23 +13,33 @@ public static class IFreeSqlExtenssions { /// /// /// + /// 数据过滤 + 验证 /// - public static DefaultRepository GetRepository(this IFreeSql that) where TEntity : class { + public static DefaultRepository GetRepository(this IFreeSql that, Expression> filter = null) where TEntity : class { - return dicGetRepository.GetOrAdd(typeof(TEntity), type1 => new ConcurrentDictionary()) - .GetOrAdd(typeof(TKey), type2 => new DefaultRepository(that)) as DefaultRepository; + return dicGetRepository + .GetOrAdd(typeof(TEntity), key1 => new ConcurrentDictionary>()) + .GetOrAdd(typeof(TKey), key2 => new ConcurrentDictionary()) + .GetOrAdd(string.Concat(filter), key3 => new DefaultRepository(that, filter)) as DefaultRepository; } - static ConcurrentDictionary> dicGetRepository = new ConcurrentDictionary>(); + static ConcurrentDictionary> + > dicGetRepository = new ConcurrentDictionary>>(); /// /// 返回仓库类,适用 Insert 方法无须返回插入的数据 /// /// /// + /// 数据过滤 + 验证 /// - public static GuidRepository GetGuidRepository(this IFreeSql that) where TEntity : class { + public static GuidRepository GetGuidRepository(this IFreeSql that, Expression> filter = null) where TEntity : class { - return dicGetGuidRepository.GetOrAdd(typeof(TEntity), type1 => new GuidRepository(that)) as GuidRepository; + return dicGetGuidRepository + .GetOrAdd(typeof(TEntity), key1 => new ConcurrentDictionary()) + .GetOrAdd(string.Concat(filter), key2 => new GuidRepository(that, filter)) as GuidRepository; } - static ConcurrentDictionary dicGetGuidRepository = new ConcurrentDictionary(); + static ConcurrentDictionary> dicGetGuidRepository = new ConcurrentDictionary>(); } \ No newline at end of file diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index cdeccd30..9730d56d 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.1.6 + 0.1.7 true YeXiangQin 打造 .NETCore 最方便的 ORM,DbFirst 与 CodeFirst 混合使用,提供从实体同步数据库,或者从数据库生成实体代码,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite 数据库。 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index 81b02672..e2352617 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -28,6 +28,13 @@ namespace FreeSql { T1 ToOne(); Task ToOneAsync(); + /// + /// 执行SQL查询,返回 T1 实体所有字段的第一条记录,记录不存在时返回 null + /// + /// + T1 First(); + Task FirstAsync(); + /// /// 返回即将执行的SQL语句 /// diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 8e8f567a..9deeb898 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -203,6 +203,7 @@ namespace FreeSql.Internal { } internal string ExpressionLambdaToSql(Expression exp, List _tables, List _selectColumnMap, Func getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName) { + if (exp == null) return ""; switch (exp.NodeType) { case ExpressionType.Not: return $"not({ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})"; case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 0b0ade7d..de51d352 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -205,6 +205,9 @@ namespace FreeSql.Internal.CommonProvider { return (await this.ToListAsync()).FirstOrDefault(); } + public T1 First() => this.ToOne(); + public Task FirstAsync() => this.ToOneAsync(); + protected List ToListMapReader((ReadAnonymousTypeInfo map, string field) af) { var sql = this.ToSql(af.field); if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}"; @@ -461,7 +464,7 @@ namespace FreeSql.Internal.CommonProvider { return (await this.ToListMapReaderAsync((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault(); } - protected TSelect InternalWhere(Expression exp) => this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null)); + protected TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null)); protected TSelect InternalJoin(Expression exp) { return this as TSelect;