From 1f0fccf977a6483215b1320493687165385152b1 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Sun, 10 Dec 2023 21:55:54 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20IUpdate.ExecuteUpdated?= =?UTF-8?q?=20=E6=8C=87=E5=AE=9A=E5=AD=97=E6=AE=B5=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=EF=BC=9B#1681?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 105 +------- FreeSql/Interface/Curd/IUpdate.cs | 13 +- .../Internal/CommonProvider/UpdateProvider.cs | 239 +++++++---------- .../CommonProvider/UpdateProviderAsync.cs | 240 +++++++----------- 4 files changed, 208 insertions(+), 389 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index f6502a75..c423ca76 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1104,82 +1104,6 @@ - - - 动态创建实体类型 - - - - - 配置Class - - 类名 - 类标记的特性[Table(Name = "xxx")] [Index(xxxx)] - - - - - 配置属性 - - 属性名称 - 属性类型 - 属性标记的特性-支持多个 - - - - - 配置属性 - - 属性名称 - 属性类型 - 该属性是否重写父类属性 - 属性标记的特性-支持多个 - - - - - 配置属性 - - 属性名称 - 属性类型 - 该属性是否重写父类属性 - 属性默认值 - 属性标记的特性-支持多个 - - - - - 配置父类 - - 父类类型 - - - - - Override属性 - - - - - - Emit动态创建出Class - Type - - - - - - 首字母小写 - - - - - - - 首字母大写 - - - - 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 null @@ -3346,6 +3270,13 @@ + + + 执行SQL语句,返回更新后的记录 + 注意:此方法只有 Postgresql/SqlServer 有效果 + + + 指定事务对象 @@ -5877,28 +5808,6 @@ 请使用 fsql.InsertDict(dict) 方法插入字典数据 - - - 动态构建Class Type - - - - - - 根据字典,创建 table 对应的实体对象 - - - - - - - - 根据实体对象,创建 table 对应的字典 - - - - - C#: that >= between && that <= and diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 1224f769..5cf46f3a 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -286,11 +286,18 @@ namespace FreeSql /// /// List ExecuteUpdated(); + List ExecuteUpdated(Expression> returnColumns); #if net40 #else - Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default); - Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default); + Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default); + /// + /// 执行SQL语句,返回更新后的记录 + /// 注意:此方法只有 Postgresql/SqlServer 有效果 + /// + /// + Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default); + Task> ExecuteUpdatedAsync(Expression> returnColumns, CancellationToken cancellationToken = default); #endif - } + } } \ No newline at end of file diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index b17e2fa4..bc423555 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -350,156 +350,105 @@ namespace FreeSql.Internal.CommonProvider ret[a] = _source.GetRange(a * takeMax, Math.Min(takeMax, _source.Count - a * takeMax)); return ret; } - protected virtual int SplitExecuteAffrows(int valuesLimit, int parameterLimit) + void SplitExecute(int valuesLimit, int parameterLimit, string traceName, Action execute) { - var ss = SplitSource(valuesLimit, parameterLimit); - var ret = 0; - if (ss.Length <= 1) - { - if (_source?.Any() == true) _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); - ret = this.RawExecuteAffrows(); - ClearData(); - return ret; - } - if (_transaction == null) - { - var threadTransaction = _orm.Ado.TransactionCurrentThread; - if (threadTransaction != null) this.WithTransaction(threadTransaction); - } + var ss = SplitSource(valuesLimit, parameterLimit); + if (ss.Length <= 1) + { + if (_source?.Any() == true) _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); + execute(); + ClearData(); + return; + } + if (_transaction == null) + { + var threadTransaction = _orm.Ado.TransactionCurrentThread; + if (threadTransaction != null) this.WithTransaction(threadTransaction); + } - var before = new Aop.TraceBeforeEventArgs("SplitExecuteAffrows", null); - _orm.Aop.TraceBeforeHandler?.Invoke(this, before); - Exception exception = null; - try - { - if (_transaction != null || _batchAutoTransaction == false) - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret += this.RawExecuteAffrows(); - } - } - else - { - if (_orm.Ado.MasterPool == null) throw new Exception(CoreStrings.MasterPool_IsNull_UseTransaction); - using (var conn = _orm.Ado.MasterPool.Get()) - { - _transaction = conn.Value.BeginTransaction(); - var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null); - _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret += this.RawExecuteAffrows(); - } - _transaction.Commit(); - _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, CoreStrings.Commit, null)); - } - catch (Exception ex) - { - _transaction.Rollback(); - _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, CoreStrings.RollBack, ex)); - throw; - } - _transaction = null; - } - } - } - catch (Exception ex) - { - exception = ex; - throw; - } - finally - { - var after = new Aop.TraceAfterEventArgs(before, null, exception); - _orm.Aop.TraceAfterHandler?.Invoke(this, after); - } - ClearData(); + var before = new Aop.TraceBeforeEventArgs(traceName, null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, before); + Exception exception = null; + try + { + if (_transaction != null || _batchAutoTransaction == false) + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); + execute(); + } + } + else + { + if (_orm.Ado.MasterPool == null) throw new Exception(CoreStrings.MasterPool_IsNull_UseTransaction); + using (var conn = _orm.Ado.MasterPool.Get()) + { + _transaction = conn.Value.BeginTransaction(); + var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); + execute(); + } + _transaction.Commit(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, CoreStrings.Commit, null)); + } + catch (Exception ex) + { + _transaction.Rollback(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, CoreStrings.RollBack, ex)); + throw; + } + _transaction = null; + } + } + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.TraceAfterEventArgs(before, null, exception); + _orm.Aop.TraceAfterHandler?.Invoke(this, after); + } + ClearData(); + } + + protected virtual int SplitExecuteAffrows(int valuesLimit, int parameterLimit) + { + var ret = 0; + SplitExecute(valuesLimit, parameterLimit, "SplitExecuteAffrows", () => + ret += this.RawExecuteAffrows() + ); return ret; } - protected virtual List SplitExecuteUpdated(int valuesLimit, int parameterLimit) { - var ss = SplitSource(valuesLimit, parameterLimit); var ret = new List(); - if (ss.Length <= 1) - { - if (_source?.Any() == true) _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); - ret = this.RawExecuteUpdated(); - ClearData(); - return ret; - } - if (_transaction == null) - { - var threadTransaction = _orm.Ado.TransactionCurrentThread; - if (threadTransaction != null) this.WithTransaction(threadTransaction); - } + SplitExecute(valuesLimit, parameterLimit, "SplitExecuteUpdated", () => + ret.AddRange(this.RawExecuteUpdated()) + ); + return ret; + } + protected virtual List SplitExecuteUpdated(int valuesLimit, int parameterLimit, Expression> returnColumns) + { + var ret = new List(); + SplitExecute(valuesLimit, parameterLimit, "SplitExecuteUpdated", () => + ret.AddRange(this.RawExecuteUpdated(returnColumns)) + ); + return ret; + } + #endregion - var before = new Aop.TraceBeforeEventArgs("SplitExecuteUpdated", null); - _orm.Aop.TraceBeforeHandler?.Invoke(this, before); - Exception exception = null; - try - { - if (_transaction != null || _batchAutoTransaction == false) - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret.AddRange(this.RawExecuteUpdated()); - } - } - else - { - if (_orm.Ado.MasterPool == null) throw new Exception(CoreStrings.MasterPool_IsNull_UseTransaction); - using (var conn = _orm.Ado.MasterPool.Get()) - { - _transaction = conn.Value.BeginTransaction(); - var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null); - _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret.AddRange(this.RawExecuteUpdated()); - } - _transaction.Commit(); - _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, CoreStrings.Commit, null)); - } - catch (Exception ex) - { - _transaction.Rollback(); - _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, CoreStrings.RollBack, ex)); - throw; - } - _transaction = null; - } - } - } - catch (Exception ex) - { - exception = ex; - throw; - } - finally - { - var after = new Aop.TraceAfterEventArgs(before, null, exception); - _orm.Aop.TraceAfterHandler?.Invoke(this, after); - } - ClearData(); - return ret; - } - #endregion - - protected int RawExecuteAffrows() + protected int RawExecuteAffrows() { var affrows = 0; DbParameter[] dbParms = null; @@ -532,11 +481,13 @@ namespace FreeSql.Internal.CommonProvider } protected abstract List RawExecuteUpdated(); + protected abstract List RawExecuteUpdated(Expression> returnColumns); - public abstract int ExecuteAffrows(); + public abstract int ExecuteAffrows(); public abstract List ExecuteUpdated(); + public abstract List ExecuteUpdated(Expression> returnColumns); - public IUpdate IgnoreColumns(Expression> columns) => IgnoreColumns(_commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, null, columns?.Body, false, null)); + public IUpdate IgnoreColumns(Expression> columns) => IgnoreColumns(_commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, null, columns?.Body, false, null)); public IUpdate UpdateColumns(Expression> columns) => UpdateColumns(_commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, null, columns?.Body, false, null)); public IUpdate IgnoreColumns(string[] columns) diff --git a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs index b06f9d79..1538f08b 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProviderAsync.cs @@ -18,154 +18,104 @@ namespace FreeSql.Internal.CommonProvider { #if net40 #else - async protected virtual Task SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit, CancellationToken cancellationToken = default) + async protected virtual Task SplitExecuteAsync(int valuesLimit, int parameterLimit, string traceName, Func executeAsync, CancellationToken cancellationToken = default) { - var ss = SplitSource(valuesLimit, parameterLimit); - var ret = 0; - if (ss.Length <= 1) - { - if (_source?.Any() == true) _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); - ret = await this.RawExecuteAffrowsAsync(cancellationToken); - ClearData(); - return ret; - } - if (_transaction == null) - { - var threadTransaction = _orm.Ado.TransactionCurrentThread; - if (threadTransaction != null) this.WithTransaction(threadTransaction); - } + var ss = SplitSource(valuesLimit, parameterLimit); + if (ss.Length <= 1) + { + if (_source?.Any() == true) _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); + await executeAsync(); + ClearData(); + return; + } + if (_transaction == null) + { + var threadTransaction = _orm.Ado.TransactionCurrentThread; + if (threadTransaction != null) this.WithTransaction(threadTransaction); + } - var before = new Aop.TraceBeforeEventArgs("SplitExecuteAffrowsAsync", null); - _orm.Aop.TraceBeforeHandler?.Invoke(this, before); - Exception exception = null; - try - { - if (_transaction != null || _batchAutoTransaction == false) - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret += await this.RawExecuteAffrowsAsync(cancellationToken); - } - } - else - { - if (_orm.Ado.MasterPool == null) throw new Exception(CoreStrings.MasterPool_IsNull_UseTransaction); - using (var conn = await _orm.Ado.MasterPool.GetAsync()) - { - _transaction = conn.Value.BeginTransaction(); - var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null); - _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret += await this.RawExecuteAffrowsAsync(cancellationToken); - } - _transaction.Commit(); - _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, CoreStrings.Commit, null)); - } - catch (Exception ex) - { - _transaction.Rollback(); - _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, CoreStrings.RollBack, ex)); - throw; - } - _transaction = null; - } - } - } - catch (Exception ex) - { - exception = ex; - throw; - } - finally - { - var after = new Aop.TraceAfterEventArgs(before, null, exception); - _orm.Aop.TraceAfterHandler?.Invoke(this, after); - } - ClearData(); + var before = new Aop.TraceBeforeEventArgs(traceName, null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, before); + Exception exception = null; + try + { + if (_transaction != null || _batchAutoTransaction == false) + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); + await executeAsync(); + } + } + else + { + if (_orm.Ado.MasterPool == null) throw new Exception(CoreStrings.MasterPool_IsNull_UseTransaction); + using (var conn = await _orm.Ado.MasterPool.GetAsync()) + { + _transaction = conn.Value.BeginTransaction(); + var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null); + _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore); + try + { + for (var a = 0; a < ss.Length; a++) + { + _source = ss[a]; + _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); + await executeAsync(); + } + _transaction.Commit(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, CoreStrings.Commit, null)); + } + catch (Exception ex) + { + _transaction.Rollback(); + _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, CoreStrings.RollBack, ex)); + throw; + } + _transaction = null; + } + } + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.TraceAfterEventArgs(before, null, exception); + _orm.Aop.TraceAfterHandler?.Invoke(this, after); + } + ClearData(); + } + + async protected virtual Task SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit, CancellationToken cancellationToken = default) + { + var ret = 0; + await SplitExecuteAsync(valuesLimit, parameterLimit, "SplitExecuteAffrowsAsync", async () => + ret += await this.RawExecuteAffrowsAsync(cancellationToken) + ); return ret; } async protected virtual Task> SplitExecuteUpdatedAsync(int valuesLimit, int parameterLimit, CancellationToken cancellationToken = default) { - var ss = SplitSource(valuesLimit, parameterLimit); - var ret = new List(); - if (ss.Length <= 1) - { - if (_source?.Any() == true) _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); - ret = await this.RawExecuteUpdatedAsync(cancellationToken); - ClearData(); - return ret; - } - if (_transaction == null) - { - var threadTransaction = _orm.Ado.TransactionCurrentThread; - if (threadTransaction != null) this.WithTransaction(threadTransaction); - } + var ret = new List(); + await SplitExecuteAsync(valuesLimit, parameterLimit, "SplitExecuteUpdatedAsync", async () => + ret.AddRange(await this.RawExecuteUpdatedAsync(cancellationToken)) + ); + return ret; + } + async protected virtual Task> SplitExecuteUpdatedAsync(int valuesLimit, int parameterLimit, Expression> returnColumns, CancellationToken cancellationToken = default) + { + var ret = new List(); + await SplitExecuteAsync(valuesLimit, parameterLimit, "SplitExecuteUpdatedAsync", async () => + ret.AddRange(await this.RawExecuteUpdatedAsync(returnColumns, cancellationToken)) + ); + return ret; + } - var before = new Aop.TraceBeforeEventArgs("SplitExecuteUpdatedAsync", null); - _orm.Aop.TraceBeforeHandler?.Invoke(this, before); - Exception exception = null; - try - { - if (_transaction != null || _batchAutoTransaction == false) - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret.AddRange(await this.RawExecuteUpdatedAsync(cancellationToken)); - } - } - else - { - if (_orm.Ado.MasterPool == null) throw new Exception(CoreStrings.MasterPool_IsNull_UseTransaction); - using (var conn = await _orm.Ado.MasterPool.GetAsync()) - { - _transaction = conn.Value.BeginTransaction(); - var transBefore = new Aop.TraceBeforeEventArgs("BeginTransaction", null); - _orm.Aop.TraceBeforeHandler?.Invoke(this, transBefore); - try - { - for (var a = 0; a < ss.Length; a++) - { - _source = ss[a]; - _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret.AddRange(await this.RawExecuteUpdatedAsync(cancellationToken)); - } - _transaction.Commit(); - _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, CoreStrings.Commit, null)); - } - catch (Exception ex) - { - _transaction.Rollback(); - _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, CoreStrings.RollBack, ex)); - throw; - } - _transaction = null; - } - } - } - catch (Exception ex) - { - exception = ex; - throw; - } - finally - { - var after = new Aop.TraceAfterEventArgs(before, null, exception); - _orm.Aop.TraceAfterHandler?.Invoke(this, after); - } - ClearData(); - return ret; - } - - async protected Task RawExecuteAffrowsAsync(CancellationToken cancellationToken = default) + async protected Task RawExecuteAffrowsAsync(CancellationToken cancellationToken = default) { var affrows = 0; DbParameter[] dbParms = null; @@ -197,9 +147,11 @@ namespace FreeSql.Internal.CommonProvider return affrows; } protected abstract Task> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default); + protected abstract Task> RawExecuteUpdatedAsync(Expression> returnColumns, CancellationToken cancellationToken = default); - public abstract Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default); - public abstract Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default); + public abstract Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default); + public abstract Task> ExecuteUpdatedAsync(CancellationToken cancellationToken = default); + public abstract Task> ExecuteUpdatedAsync(Expression> returnColumns, CancellationToken cancellationToken = default); #endif - } + } }