From 4f66c3b9eb3900ce9c5e1cecd706a1f3d5f28d1c Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Mon, 11 Mar 2019 17:26:27 +0800 Subject: [PATCH] ## v0.3.11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 增加 ISelect、IInsert、IUpdate、IDelete WithTransaction 方法,将事务对象暴露给外部; - 增加 IAdo ExecuteXxx 系列方法重载,支持事务对象的传入; --- Examples/repository_01/Startup.cs | 2 +- .../AutofacExtenssions.cs} | 4 +- .../{ => Extenssions}/IFreeSqlExtenssions.cs | 2 +- FreeSql.Repository/FreeSql.Repository.csproj | 2 +- FreeSql/FreeSql.csproj | 2 +- FreeSql/Interface/Curd/IDelete.cs | 9 +++ FreeSql/Interface/Curd/IInsert.cs | 8 +++ FreeSql/Interface/Curd/ISelect/ISelect0.cs | 8 +++ FreeSql/Interface/Curd/IUpdate.cs | 8 +++ FreeSql/Interface/IAdo.cs | 24 ++++++++ .../CommonProvider/AdoProvider/AdoProvider.cs | 60 +++++++++++------- .../AdoProvider/AdoProviderAsync.cs | 61 +++++++++++++------ .../AdoProvider/AdoProviderTransaction.cs | 22 +------ .../Internal/CommonProvider/DeleteProvider.cs | 10 ++- .../Internal/CommonProvider/InsertProvider.cs | 10 ++- .../SelectProvider/Select0Provider.cs | 19 ++++-- .../Internal/CommonProvider/UpdateProvider.cs | 10 ++- FreeSql/MySql/Curd/MySqlDelete.cs | 4 +- FreeSql/MySql/Curd/MySqlInsert.cs | 8 +-- FreeSql/MySql/Curd/MySqlUpdate.cs | 4 +- FreeSql/Oracle/Curd/OracleInsert.cs | 10 +-- FreeSql/PostgreSQL/Curd/PostgreSQLDelete.cs | 4 +- FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs | 12 ++-- FreeSql/PostgreSQL/Curd/PostgreSQLUpdate.cs | 4 +- FreeSql/SqlServer/Curd/SqlServerDelete.cs | 4 +- FreeSql/SqlServer/Curd/SqlServerInsert.cs | 8 +-- FreeSql/SqlServer/Curd/SqlServerUpdate.cs | 4 +- FreeSql/Sqlite/Curd/SqliteInsert.cs | 4 +- readme.md | 4 +- 29 files changed, 216 insertions(+), 115 deletions(-) rename FreeSql.Repository/{DependencyInjection.cs => Extenssions/AutofacExtenssions.cs} (97%) rename FreeSql.Repository/{ => Extenssions}/IFreeSqlExtenssions.cs (97%) diff --git a/Examples/repository_01/Startup.cs b/Examples/repository_01/Startup.cs index da0c513f..9a44a520 100644 --- a/Examples/repository_01/Startup.cs +++ b/Examples/repository_01/Startup.cs @@ -67,7 +67,7 @@ namespace repository_01 { var builder = new ContainerBuilder(); - builder.RegisterFreeRepositoryAddFilter(() => a => a.Title == DateTime.Now.ToString() + System.Threading.Thread.CurrentThread.ManagedThreadId); + 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.Populate(services); diff --git a/FreeSql.Repository/DependencyInjection.cs b/FreeSql.Repository/Extenssions/AutofacExtenssions.cs similarity index 97% rename from FreeSql.Repository/DependencyInjection.cs rename to FreeSql.Repository/Extenssions/AutofacExtenssions.cs index 50c87bb4..cecfeafc 100644 --- a/FreeSql.Repository/DependencyInjection.cs +++ b/FreeSql.Repository/Extenssions/AutofacExtenssions.cs @@ -6,10 +6,10 @@ using System.Collections.Concurrent; using System.Linq.Expressions; using System.Reflection; -public static class FreeSqlRepositoryAutofacDependencyInjection { +public static class FreeSqlRepositoryAutofacExtenssions { public static void RegisterFreeRepository(this ContainerBuilder builder) => RegisterFreeRepositoryPrivate(builder, null, null); - public static void RegisterFreeRepositoryAddFilter(this ContainerBuilder builder, Func>> filterHandler) => RegisterFreeRepositoryPrivate(builder, filterHandler, null); + public static void RegisterFreeRepositoryAndFilter(this ContainerBuilder builder, Func>> filterHandler) => RegisterFreeRepositoryPrivate(builder, filterHandler, null); static ConcurrentDictionary _dicRegisterFreeRepositorySetFilterFunc = new ConcurrentDictionary(); static ConcurrentDictionary _dicRegisterFreeRepositorySetAsTableFunc = new ConcurrentDictionary(); diff --git a/FreeSql.Repository/IFreeSqlExtenssions.cs b/FreeSql.Repository/Extenssions/IFreeSqlExtenssions.cs similarity index 97% rename from FreeSql.Repository/IFreeSqlExtenssions.cs rename to FreeSql.Repository/Extenssions/IFreeSqlExtenssions.cs index 7c9e0346..4073a702 100644 --- a/FreeSql.Repository/IFreeSqlExtenssions.cs +++ b/FreeSql.Repository/Extenssions/IFreeSqlExtenssions.cs @@ -5,7 +5,7 @@ using System.Collections.Concurrent; using System.Text; using System.Linq.Expressions; -public static class IFreeSqlExtenssions { +public static class FreeSqlRepositoryIFreeSqlExtenssions { /// /// 返回默认仓库类 diff --git a/FreeSql.Repository/FreeSql.Repository.csproj b/FreeSql.Repository/FreeSql.Repository.csproj index 05cdce70..4cb0d516 100644 --- a/FreeSql.Repository/FreeSql.Repository.csproj +++ b/FreeSql.Repository/FreeSql.Repository.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.1.14 + 0.3.11 YeXiangQin FreeSql 通用仓库层实现,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite,读写分离、分表分库。 https://github.com/2881099/FreeSql diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index c9b9a504..f402bfdc 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.1.14 + 0.3.11 true YeXiangQin 打造 .NETCore 最方便的 ORM,DbFirst 与 CodeFirst 混合使用,提供从实体同步数据库,或者从数据库生成实体代码,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite,读写分离、分表分库。 diff --git a/FreeSql/Interface/Curd/IDelete.cs b/FreeSql/Interface/Curd/IDelete.cs index 5d70b1df..6b40250c 100644 --- a/FreeSql/Interface/Curd/IDelete.cs +++ b/FreeSql/Interface/Curd/IDelete.cs @@ -1,10 +1,19 @@ using System; using System.Collections.Generic; +using System.Data.Common; using System.Linq.Expressions; using System.Threading.Tasks; namespace FreeSql { public interface IDelete where T1 : class { + + /// + /// 指定事务对象 + /// + /// + /// + IDelete WithTransaction(DbTransaction transaction); + /// /// lambda表达式条件,仅支持实体基础成员(不包含导航对象) /// diff --git a/FreeSql/Interface/Curd/IInsert.cs b/FreeSql/Interface/Curd/IInsert.cs index 2d6582af..1661b07d 100644 --- a/FreeSql/Interface/Curd/IInsert.cs +++ b/FreeSql/Interface/Curd/IInsert.cs @@ -1,11 +1,19 @@ using System; using System.Collections.Generic; +using System.Data.Common; using System.Linq.Expressions; using System.Threading.Tasks; namespace FreeSql { public interface IInsert where T1 : class { + /// + /// 指定事务对象 + /// + /// + /// + IInsert WithTransaction(DbTransaction transaction); + /// /// 追加准备插入的实体 /// diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index efda1ca1..f0ca6378 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Data.Common; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; @@ -7,6 +8,13 @@ using System.Threading.Tasks; namespace FreeSql { public interface ISelect0 { + /// + /// 指定事务对象 + /// + /// + /// + TSelect WithTransaction(DbTransaction transaction); + /// /// 执行SQL查询,返回 T1 实体所有字段的记录,记录不存在时返回 Count 为 0 的列表 /// diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 8e1ea93c..6059cf6f 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -1,11 +1,19 @@ using System; using System.Collections.Generic; +using System.Data.Common; using System.Linq.Expressions; using System.Threading.Tasks; namespace FreeSql { public interface IUpdate where T1 : class { + /// + /// 指定事务对象 + /// + /// + /// + IUpdate WithTransaction(DbTransaction transaction); + /// /// 更新数据,设置更新的实体 /// diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index 1f40a49e..79c8ff7e 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -61,18 +61,21 @@ namespace FreeSql { /// /// void ExecuteReader(Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + void ExecuteReader(DbTransaction transaction, Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 查询,ExecuteReader(dr => {}, "select * from user where age > @age", new { age = 25 }) /// /// /// void ExecuteReader(Action readerHander, string cmdText, object parms = null); + void ExecuteReader(DbTransaction transaction, Action readerHander, string cmdText, object parms = null); /// /// 查询 /// /// /// object[][] ExecuteArray(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + object[][] ExecuteArray(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 查询,ExecuteArray("select * from user where age > @age", new { age = 25 }) /// @@ -80,12 +83,14 @@ namespace FreeSql { /// /// object[][] ExecuteArray(string cmdText, object parms = null); + object[][] ExecuteArray(DbTransaction transaction, string cmdText, object parms = null); /// /// 查询 /// /// /// DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + DataTable ExecuteDataTable(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 查询,ExecuteDataTable("select * from user where age > @age", new { age = 25 }) /// @@ -93,6 +98,7 @@ namespace FreeSql { /// /// DataTable ExecuteDataTable(string cmdText, object parms = null); + DataTable ExecuteDataTable(DbTransaction transaction, string cmdText, object parms = null); /// /// 在【主库】执行 /// @@ -100,6 +106,7 @@ namespace FreeSql { /// /// int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + int ExecuteNonQuery(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 在【主库】执行,ExecuteNonQuery("delete from user where age > @age", new { age = 25 }) /// @@ -107,6 +114,7 @@ namespace FreeSql { /// /// int ExecuteNonQuery(string cmdText, object parms = null); + int ExecuteNonQuery(DbTransaction transaction, string cmdText, object parms = null); /// /// 在【主库】执行 /// @@ -114,6 +122,7 @@ namespace FreeSql { /// /// object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + object ExecuteScalar(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 在【主库】执行,ExecuteScalar("select 1 from user where age > @age", new { age = 25 }) /// @@ -121,6 +130,7 @@ namespace FreeSql { /// /// object ExecuteScalar(string cmdText, object parms = null); + object ExecuteScalar(DbTransaction transaction, string cmdText, object parms = null); /// /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 }) @@ -131,6 +141,7 @@ namespace FreeSql { /// /// List Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + List Query(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new { age = 25 }) /// @@ -139,6 +150,7 @@ namespace FreeSql { /// /// List Query(string cmdText, object parms = null); + List Query(DbTransaction transaction, string cmdText, object parms = null); #region async /// @@ -149,18 +161,21 @@ namespace FreeSql { /// /// Task ExecuteReaderAsync(Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 }) /// /// /// Task ExecuteReaderAsync(Func readerHander, string cmdText, object parms = null); + Task ExecuteReaderAsync(DbTransaction transaction, Func readerHander, string cmdText, object parms = null); /// /// 查询 /// /// /// Task ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteArrayAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 }) /// @@ -168,12 +183,14 @@ namespace FreeSql { /// /// Task ExecuteArrayAsync(string cmdText, object parms = null); + Task ExecuteArrayAsync(DbTransaction transaction, string cmdText, object parms = null); /// /// 查询 /// /// /// Task ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteDataTableAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 查询,ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 }) /// @@ -181,6 +198,7 @@ namespace FreeSql { /// /// Task ExecuteDataTableAsync(string cmdText, object parms = null); + Task ExecuteDataTableAsync(DbTransaction transaction, string cmdText, object parms = null); /// /// 在【主库】执行 /// @@ -188,6 +206,7 @@ namespace FreeSql { /// /// Task ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteNonQueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 }) /// @@ -195,6 +214,7 @@ namespace FreeSql { /// /// Task ExecuteNonQueryAsync(string cmdText, object parms = null); + Task ExecuteNonQueryAsync(DbTransaction transaction, string cmdText, object parms = null); /// /// 在【主库】执行 /// @@ -202,6 +222,7 @@ namespace FreeSql { /// /// Task ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task ExecuteScalarAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 }) /// @@ -209,6 +230,7 @@ namespace FreeSql { /// /// Task ExecuteScalarAsync(string cmdText, object parms = null); + Task ExecuteScalarAsync(DbTransaction transaction, string cmdText, object parms = null); /// /// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 }) @@ -219,6 +241,7 @@ namespace FreeSql { /// /// Task> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms); + Task> QueryAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms); /// /// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new { age = 25 }) /// @@ -227,6 +250,7 @@ namespace FreeSql { /// /// Task> QueryAsync(string cmdText, object parms = null); + Task> QueryAsync(DbTransaction transaction, string cmdText, object parms = null); #endregion } } diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index bebff47d..ed5020ef 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -58,7 +58,13 @@ namespace FreeSql.Internal.CommonProvider { log.Append(e.Message); _log.LogError(log.ToString()); - RollbackTransaction(); + if (cmd.Transaction != null) { + var curTran = TransactionCurrentThread; + if (cmd.Transaction != TransactionCurrentThread) { + //cmd.Transaction.Rollback(); + } else + RollbackTransaction(); + } AopCommandExecuted?.Invoke(cmd, log.ToString()); @@ -67,13 +73,15 @@ namespace FreeSql.Internal.CommonProvider { } internal static ConcurrentDictionary dicQueryTypeGetProperties = new ConcurrentDictionary(); - public List Query(string cmdText, object parms = null) => Query(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public List Query(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { + public List Query(string cmdText, object parms = null) => Query(null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public List Query(DbTransaction transaction, string cmdText, object parms = null) => Query(transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + 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(); var type = typeof(T); int[] indexes = null; var props = dicQueryTypeGetProperties.GetOrAdd(type, k => type.GetProperties()); - ExecuteReader(dr => { + ExecuteReader(transaction, dr => { if (indexes == null) { var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) @@ -84,8 +92,10 @@ namespace FreeSql.Internal.CommonProvider { }, cmdType, cmdText, cmdParms); return ret; } - public void ExecuteReader(Action readerHander, string cmdText, object parms = null) => ExecuteReader(readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public void ExecuteReader(Action readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { + public void ExecuteReader(Action readerHander, string cmdText, object parms = null) => ExecuteReader(null, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + 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) { var dt = DateTime.Now; var logtxt = new StringBuilder(); var logtxt_dt = DateTime.Now; @@ -108,7 +118,7 @@ namespace FreeSql.Internal.CommonProvider { } Object conn = null; - var pc = PrepareCommand(cmdType, cmdText, cmdParms, logtxt); + var pc = PrepareCommand(transaction, cmdType, cmdText, cmdParms, logtxt); if (IsTracePerformance) logtxt.Append("PrepareCommand: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); Exception ex = null; try { @@ -178,20 +188,24 @@ namespace FreeSql.Internal.CommonProvider { LoggerException(pool, pc.cmd, ex, dt, logtxt); pc.cmd.Parameters.Clear(); } - public object[][] ExecuteArray(string cmdText, object parms = null) => ExecuteArray(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public object[][] ExecuteArray(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { + public object[][] ExecuteArray(string cmdText, object parms = null) => ExecuteArray(null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public object[][] ExecuteArray(DbTransaction transaction, string cmdText, object parms = null) => ExecuteArray(transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public object[][] ExecuteArray(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArray(null, cmdType, cmdText, cmdParms); + public object[][] ExecuteArray(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { List ret = new List(); - ExecuteReader(dr => { + ExecuteReader(transaction, dr => { object[] values = new object[dr.FieldCount]; dr.GetValues(values); ret.Add(values); }, cmdType, cmdText, cmdParms); return ret.ToArray(); } - public DataTable ExecuteDataTable(string cmdText, object parms = null) => ExecuteDataTable(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { + public DataTable ExecuteDataTable(string cmdText, object parms = null) => ExecuteDataTable(null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public DataTable ExecuteDataTable(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTable(transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTable(null, cmdType, cmdText, cmdParms); + public DataTable ExecuteDataTable(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var ret = new DataTable(); - ExecuteReader(dr => { + ExecuteReader(transaction, dr => { if (ret.Columns.Count == 0) for (var a = 0; a < dr.FieldCount; a++) ret.Columns.Add(dr.GetName(a)); object[] values = new object[ret.Columns.Count]; @@ -200,13 +214,15 @@ namespace FreeSql.Internal.CommonProvider { }, cmdType, cmdText, cmdParms); return ret; } - public int ExecuteNonQuery(string cmdText, object parms = null) => ExecuteNonQuery(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { + public int ExecuteNonQuery(string cmdText, object parms = null) => ExecuteNonQuery(null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + 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) { var dt = DateTime.Now; var logtxt = new StringBuilder(); var logtxt_dt = DateTime.Now; Object conn = null; - var pc = PrepareCommand(cmdType, cmdText, cmdParms, logtxt); + var pc = PrepareCommand(transaction, cmdType, cmdText, cmdParms, logtxt); int val = 0; Exception ex = null; try { @@ -225,13 +241,15 @@ namespace FreeSql.Internal.CommonProvider { pc.cmd.Parameters.Clear(); return val; } - public object ExecuteScalar(string cmdText, object parms = null) => ExecuteScalar(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - public object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { + public object ExecuteScalar(string cmdText, object parms = null) => ExecuteScalar(null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + 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) { var dt = DateTime.Now; var logtxt = new StringBuilder(); var logtxt_dt = DateTime.Now; Object conn = null; - var pc = PrepareCommand(cmdType, cmdText, cmdParms, logtxt); + var pc = PrepareCommand(transaction, cmdType, cmdText, cmdParms, logtxt); object val = null; Exception ex = null; try { @@ -251,7 +269,7 @@ namespace FreeSql.Internal.CommonProvider { return val; } - private (DbTransaction tran, DbCommand cmd) PrepareCommand(CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) { + private (DbTransaction tran, DbCommand cmd) PrepareCommand(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) { var dt = DateTime.Now; DbCommand cmd = CreateCommand(); cmd.CommandType = cmdType; @@ -265,7 +283,7 @@ namespace FreeSql.Internal.CommonProvider { } } - var tran = TransactionCurrentThread; + var tran = transaction ?? TransactionCurrentThread; if (IsTracePerformance) logtxt.Append(" PrepareCommand_part1: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms cmdParms: ").Append(cmd.Parameters.Count).Append("\r\n"); if (tran != null) { diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index 316251f8..ad66ae30 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -9,13 +9,15 @@ using System.Threading.Tasks; namespace FreeSql.Internal.CommonProvider { partial class AdoProvider { - public Task> QueryAsync(string cmdText, object parms = null) => QueryAsync(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - async public Task> QueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { + public Task> QueryAsync(string cmdText, object parms = null) => QueryAsync(null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task> QueryAsync(DbTransaction transaction, string cmdText, object parms = null) => QueryAsync(transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + 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(); var type = typeof(T); int[] indexes = null; var props = dicQueryTypeGetProperties.GetOrAdd(type, k => type.GetProperties()); - await ExecuteReaderAsync(dr => { + await ExecuteReaderAsync(transaction, dr => { if (indexes == null) { var dic = new Dictionary(StringComparer.CurrentCultureIgnoreCase); for (var a = 0; a < dr.FieldCount; a++) @@ -27,8 +29,10 @@ namespace FreeSql.Internal.CommonProvider { }, cmdType, cmdText, cmdParms); return ret; } - public Task ExecuteReaderAsync(Func readerHander, string cmdText, object parms = null) => ExecuteReaderAsync(readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - async public Task ExecuteReaderAsync(Func readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { + public Task ExecuteReaderAsync(Func readerHander, string cmdText, object parms = null) => ExecuteReaderAsync(null, readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + 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) { var dt = DateTime.Now; var logtxt = new StringBuilder(); var logtxt_dt = DateTime.Now; @@ -51,7 +55,7 @@ namespace FreeSql.Internal.CommonProvider { } Object conn = null; - var cmd = PrepareCommandAsync(cmdType, cmdText, cmdParms, logtxt); + var cmd = PrepareCommandAsync(transaction, cmdType, cmdText, cmdParms, logtxt); if (IsTracePerformance) logtxt.Append("PrepareCommandAsync: ").Append(DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds).Append("ms Total: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); Exception ex = null; try { @@ -121,20 +125,24 @@ namespace FreeSql.Internal.CommonProvider { LoggerException(pool, cmd, ex, dt, logtxt); cmd.Parameters.Clear(); } - public Task ExecuteArrayAsync(string cmdText, object parms = null) => ExecuteArrayAsync(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - async public Task ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { + public Task ExecuteArrayAsync(string cmdText, object parms = null) => ExecuteArrayAsync(null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteArrayAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteArrayAsync(transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteArrayAsync(null, cmdType, cmdText, cmdParms); + async public Task ExecuteArrayAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { List ret = new List(); - await ExecuteReaderAsync(async dr => { + await ExecuteReaderAsync(transaction, async dr => { object[] values = new object[dr.FieldCount]; for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync(a); ret.Add(values); }, cmdType, cmdText, cmdParms); return ret.ToArray(); } - public Task ExecuteDataTableAsync(string cmdText, object parms = null) => ExecuteDataTableAsync(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - async public Task ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { + public Task ExecuteDataTableAsync(string cmdText, object parms = null) => ExecuteDataTableAsync(null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteDataTableAsync(DbTransaction transaction, string cmdText, object parms = null) => ExecuteDataTableAsync(transaction, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + public Task ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) => ExecuteDataTableAsync(null, cmdType, cmdText, cmdParms); + async public Task ExecuteDataTableAsync(DbTransaction transaction, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { var ret = new DataTable(); - await ExecuteReaderAsync(async dr => { + await ExecuteReaderAsync(transaction, async dr => { if (ret.Columns.Count == 0) for (var a = 0; a < dr.FieldCount; a++) ret.Columns.Add(dr.GetName(a)); object[] values = new object[ret.Columns.Count]; @@ -143,13 +151,15 @@ namespace FreeSql.Internal.CommonProvider { }, cmdType, cmdText, cmdParms); return ret; } - public Task ExecuteNonQueryAsync(string cmdText, object parms = null) => ExecuteNonQueryAsync(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - async public Task ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { + public Task ExecuteNonQueryAsync(string cmdText, object parms = null) => ExecuteNonQueryAsync(null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + 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) { var dt = DateTime.Now; var logtxt = new StringBuilder(); var logtxt_dt = DateTime.Now; Object conn = null; - var cmd = PrepareCommandAsync(cmdType, cmdText, cmdParms, logtxt); + var cmd = PrepareCommandAsync(transaction, cmdType, cmdText, cmdParms, logtxt); int val = 0; Exception ex = null; try { @@ -168,13 +178,15 @@ namespace FreeSql.Internal.CommonProvider { cmd.Parameters.Clear(); return val; } - public Task ExecuteScalarAsync(string cmdText, object parms = null) => ExecuteScalarAsync(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); - async public Task ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) { + public Task ExecuteScalarAsync(string cmdText, object parms = null) => ExecuteScalarAsync(null, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms)); + 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) { var dt = DateTime.Now; var logtxt = new StringBuilder(); var logtxt_dt = DateTime.Now; Object conn = null; - var cmd = PrepareCommandAsync(cmdType, cmdText, cmdParms, logtxt); + var cmd = PrepareCommandAsync(transaction, cmdType, cmdText, cmdParms, logtxt); object val = null; Exception ex = null; try { @@ -194,7 +206,7 @@ namespace FreeSql.Internal.CommonProvider { return val; } - private DbCommand PrepareCommandAsync(CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) { + private DbCommand PrepareCommandAsync(DbTransaction transaction, CommandType cmdType, string cmdText, DbParameter[] cmdParms, StringBuilder logtxt) { DateTime dt = DateTime.Now; DbCommand cmd = CreateCommand(); cmd.CommandType = cmdType; @@ -208,7 +220,16 @@ namespace FreeSql.Internal.CommonProvider { } } - if (IsTracePerformance) logtxt.Append(" PrepareCommand_tran==null: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms cmdParms: ").Append(cmd.Parameters.Count).Append("\r\n"); + var tran = transaction; + + if (tran != null) { + if (IsTracePerformance) dt = DateTime.Now; + cmd.Connection = tran.Connection; + cmd.Transaction = tran; + if (IsTracePerformance) logtxt.Append(" PrepareCommandAsync_tran!=null: ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms\r\n"); + } + + if (IsTracePerformance) logtxt.Append(" PrepareCommandAsync ").Append(DateTime.Now.Subtract(dt).TotalMilliseconds).Append("ms cmdParms: ").Append(cmd.Parameters.Count).Append("\r\n"); AopCommandExecuting?.Invoke(cmd); return cmd; diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs index 6807e86e..460ae498 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs @@ -47,9 +47,6 @@ namespace FreeSql.Internal.CommonProvider { } public void TransactionPreRemoveCache(params string[] key) => PreRemove(key); - /// - /// 启动事务 - /// public void BeginTransaction(TimeSpan timeout) { int tid = Thread.CurrentThread.ManagedThreadId; Transaction2 tran = null; @@ -60,6 +57,7 @@ namespace FreeSql.Internal.CommonProvider { tran = new Transaction2(conn, conn.Value.BeginTransaction(), timeout); } catch(Exception ex) { _log.LogError($"数据库出错(开启事务){ex.Message} \r\n{ex.StackTrace}"); + MasterPool.Return(conn); throw ex; } if (_trans.ContainsKey(tid)) CommitTransaction(); @@ -68,9 +66,6 @@ namespace FreeSql.Internal.CommonProvider { _trans.Add(tid, tran); } - /// - /// 自动提交事务 - /// private void AutoCommitTransaction() { if (_trans.Count > 0) { Transaction2[] trans = null; @@ -110,13 +105,7 @@ namespace FreeSql.Internal.CommonProvider { private void CommitTransaction(bool isCommit) { if (_trans.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var tran)) CommitTransaction(isCommit, tran); } - /// - /// 提交事务 - /// public void CommitTransaction() => CommitTransaction(true); - /// - /// 回滚事务 - /// public void RollbackTransaction() => CommitTransaction(false); public void Dispose() { @@ -126,18 +115,9 @@ namespace FreeSql.Internal.CommonProvider { foreach (Transaction2 tran in trans) CommitTransaction(false, tran); } - /// - /// 开启事务(不支持异步),60秒未执行完将自动提交 - /// - /// 事务体 () => {} public void Transaction(Action handler) { Transaction(handler, TimeSpan.FromSeconds(60)); } - /// - /// 开启事务(不支持异步) - /// - /// 事务体 () => {} - /// 超时,未执行完将自动提交 public void Transaction(Action handler, TimeSpan timeout) { try { BeginTransaction(timeout); diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 971cc36f..0038ad26 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -19,6 +19,7 @@ namespace FreeSql.Internal.CommonProvider { protected StringBuilder _where = new StringBuilder(); protected int _whereTimes = 0; protected List _params = new List(); + protected DbTransaction _transaction; public DeleteProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) { _orm = orm; @@ -29,15 +30,20 @@ namespace FreeSql.Internal.CommonProvider { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(); } + public IDelete WithTransaction(DbTransaction transaction) { + _transaction = transaction; + return this; + } + public int ExecuteAffrows() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return _orm.Ado.ExecuteNonQuery(CommandType.Text, sql, _params.ToArray()); + return _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, sql, _params.ToArray()); } async public Task ExecuteAffrowsAsync() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return await _orm.Ado.ExecuteNonQueryAsync(CommandType.Text, sql, _params.ToArray()); + return await _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, sql, _params.ToArray()); } public abstract List ExecuteDeleted(); public abstract Task> ExecuteDeletedAsync(); diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 61b31921..dfe29bec 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -19,6 +19,7 @@ namespace FreeSql.Internal.CommonProvider { protected TableInfo _table; protected Func _tableRule; protected DbParameter[] _params; + protected DbTransaction _transaction; public InsertProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) { _orm = orm; @@ -28,6 +29,11 @@ namespace FreeSql.Internal.CommonProvider { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(); } + public IInsert WithTransaction(DbTransaction transaction) { + _transaction = transaction; + return this; + } + public IInsert AppendData(T1 source) { if (source != null) _source.Add(source); return this; @@ -37,8 +43,8 @@ namespace FreeSql.Internal.CommonProvider { return this; } - public int ExecuteAffrows() => _orm.Ado.ExecuteNonQuery(CommandType.Text, this.ToSql(), _params); - public Task ExecuteAffrowsAsync() => _orm.Ado.ExecuteNonQueryAsync(CommandType.Text, this.ToSql(), _params); + public int ExecuteAffrows() => _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, this.ToSql(), _params); + public Task ExecuteAffrowsAsync() => _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, this.ToSql(), _params); public abstract long ExecuteIdentity(); public abstract Task ExecuteIdentityAsync(); public abstract List ExecuteInserted(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 11909523..bcdc017e 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -25,6 +25,7 @@ namespace FreeSql.Internal.CommonProvider { protected IFreeSql _orm; protected CommonUtils _commonUtils; protected CommonExpression _commonExpression; + protected DbTransaction _transaction; internal static void CopyData(Select0Provider from, object to) { var toType = to?.GetType(); @@ -44,6 +45,7 @@ namespace FreeSql.Internal.CommonProvider { //toType.GetField("_orm", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._orm); //toType.GetField("_commonUtils", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._commonUtils); //toType.GetField("_commonExpression", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._commonExpression); + toType.GetField("_transaction", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(to, from._transaction); } public Select0Provider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) { @@ -55,6 +57,11 @@ namespace FreeSql.Internal.CommonProvider { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(); } + public TSelect WithTransaction(DbTransaction transaction) { + _transaction = transaction; + return this as TSelect; + } + public bool Any() { this.Limit(1); return this.ToList("1").FirstOrDefault() == 1; @@ -152,7 +159,7 @@ namespace FreeSql.Internal.CommonProvider { return _orm.Cache.Shell(_cache.key, _cache.seconds, () => { List ret = new List(); Type type = typeof(TTuple); - _orm.Ado.ExecuteReader(dr => { + _orm.Ado.ExecuteReader(_transaction, dr => { var read = Utils.ExecuteArrayRowReadClassOrTuple(type, null, dr); ret.Add((TTuple)read.Value); }, CommandType.Text, sql, _params.ToArray()); @@ -166,7 +173,7 @@ namespace FreeSql.Internal.CommonProvider { return _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => { List ret = new List(); Type type = typeof(TTuple); - await _orm.Ado.ExecuteReaderAsync(dr => { + await _orm.Ado.ExecuteReaderAsync(_transaction, dr => { var read = Utils.ExecuteArrayRowReadClassOrTuple(type, null, dr); ret.Add((TTuple)read.Value); return Task.CompletedTask; @@ -181,7 +188,7 @@ namespace FreeSql.Internal.CommonProvider { return _orm.Cache.Shell(_cache.key, _cache.seconds, () => { List ret = new List(); - _orm.Ado.ExecuteReader(dr => { + _orm.Ado.ExecuteReader(_transaction, dr => { ret.Add(af.Read(dr)); }, CommandType.Text, sql, _params.ToArray()); return ret; @@ -194,7 +201,7 @@ namespace FreeSql.Internal.CommonProvider { return await _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => { List ret = new List(); - await _orm.Ado.ExecuteReaderAsync(dr => { + await _orm.Ado.ExecuteReaderAsync(_transaction, dr => { ret.Add(af.Read(dr)); return Task.CompletedTask; }, CommandType.Text, sql, _params.ToArray()); @@ -220,7 +227,7 @@ namespace FreeSql.Internal.CommonProvider { return _orm.Cache.Shell(_cache.key, _cache.seconds, () => { List ret = new List(); Type type = typeof(TReturn); - _orm.Ado.ExecuteReader(dr => { + _orm.Ado.ExecuteReader(_transaction, dr => { var index = -1; ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index)); }, CommandType.Text, sql, _params.ToArray()); @@ -234,7 +241,7 @@ namespace FreeSql.Internal.CommonProvider { return await _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => { List ret = new List(); Type type = typeof(TReturn); - await _orm.Ado.ExecuteReaderAsync(dr => { + await _orm.Ado.ExecuteReaderAsync(_transaction, dr => { var index = -1; ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index)); return Task.CompletedTask; diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 86f71420..14fd0c73 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -22,6 +22,7 @@ namespace FreeSql.Internal.CommonProvider { protected StringBuilder _set = new StringBuilder(); protected List _params = new List(); protected List _paramsSource = new List(); + protected DbTransaction _transaction; public UpdateProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) { _orm = orm; @@ -32,15 +33,20 @@ namespace FreeSql.Internal.CommonProvider { if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(); } + public IUpdate WithTransaction(DbTransaction transaction) { + _transaction = transaction; + return this; + } + public int ExecuteAffrows() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return _orm.Ado.ExecuteNonQuery(CommandType.Text, sql, _params.Concat(_paramsSource).ToArray()); + return _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, sql, _params.Concat(_paramsSource).ToArray()); } async public Task ExecuteAffrowsAsync() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return await _orm.Ado.ExecuteNonQueryAsync(CommandType.Text, sql, _params.Concat(_paramsSource).ToArray()); + return await _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, sql, _params.Concat(_paramsSource).ToArray()); } public abstract List ExecuteUpdated(); public abstract Task> ExecuteUpdatedAsync(); diff --git a/FreeSql/MySql/Curd/MySqlDelete.cs b/FreeSql/MySql/Curd/MySqlDelete.cs index 66f49669..0710db42 100644 --- a/FreeSql/MySql/Curd/MySqlDelete.cs +++ b/FreeSql/MySql/Curd/MySqlDelete.cs @@ -24,7 +24,7 @@ namespace FreeSql.MySql.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return _orm.Ado.Query(CommandType.Text, sb.ToString(), _params.ToArray()); + return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params.ToArray()); } async public override Task> ExecuteDeletedAsync() { var sql = this.ToSql(); @@ -39,7 +39,7 @@ namespace FreeSql.MySql.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return await _orm.Ado.QueryAsync(CommandType.Text, sb.ToString(), _params.ToArray()); + return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params.ToArray()); } } } diff --git a/FreeSql/MySql/Curd/MySqlInsert.cs b/FreeSql/MySql/Curd/MySqlInsert.cs index 96a1a9cc..eeb27ab5 100644 --- a/FreeSql/MySql/Curd/MySqlInsert.cs +++ b/FreeSql/MySql/Curd/MySqlInsert.cs @@ -15,13 +15,13 @@ namespace FreeSql.MySql.Curd { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params)), out var trylng) ? trylng : 0; + return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params)), out var trylng) ? trylng : 0; } async public override Task ExecuteIdentityAsync() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(CommandType.Text, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params)), out var trylng) ? trylng : 0; + return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params)), out var trylng) ? trylng : 0; } public override List ExecuteInserted() { @@ -37,7 +37,7 @@ namespace FreeSql.MySql.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return _orm.Ado.Query(CommandType.Text, sb.ToString(), _params); + return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params); } async public override Task> ExecuteInsertedAsync() { var sql = this.ToSql(); @@ -52,7 +52,7 @@ namespace FreeSql.MySql.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return await _orm.Ado.QueryAsync(CommandType.Text, sb.ToString(), _params); + return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params); } } } diff --git a/FreeSql/MySql/Curd/MySqlUpdate.cs b/FreeSql/MySql/Curd/MySqlUpdate.cs index d2e80615..32d6a7a0 100644 --- a/FreeSql/MySql/Curd/MySqlUpdate.cs +++ b/FreeSql/MySql/Curd/MySqlUpdate.cs @@ -27,7 +27,7 @@ namespace FreeSql.MySql.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return _orm.Ado.Query(CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); + return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); } async public override Task> ExecuteUpdatedAsync() { var sql = this.ToSql(); @@ -42,7 +42,7 @@ namespace FreeSql.MySql.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return await _orm.Ado.QueryAsync(CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); + return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); } protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { diff --git a/FreeSql/Oracle/Curd/OracleInsert.cs b/FreeSql/Oracle/Curd/OracleInsert.cs index 901189f1..40435c75 100644 --- a/FreeSql/Oracle/Curd/OracleInsert.cs +++ b/FreeSql/Oracle/Curd/OracleInsert.cs @@ -75,13 +75,13 @@ namespace FreeSql.Oracle.Curd { if (string.IsNullOrEmpty(sql)) return 0; if (_identCol == null || _source.Count > 1) { - _orm.Ado.ExecuteNonQuery(CommandType.Text, sql, _params); + _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, sql, _params); return 0; } var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.CsType, 0) as OracleParameter; identParam.Direction = ParameterDirection.Output; - _orm.Ado.ExecuteNonQuery(CommandType.Text, $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}", _params.Concat(new[] { identParam }).ToArray()); + _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}", _params.Concat(new[] { identParam }).ToArray()); return long.TryParse(string.Concat(identParam.Value), out var trylng) ? trylng : 0; } async public override Task ExecuteIdentityAsync() { @@ -89,13 +89,13 @@ namespace FreeSql.Oracle.Curd { if (string.IsNullOrEmpty(sql)) return 0; if (_identCol == null || _source.Count > 1) { - await _orm.Ado.ExecuteNonQueryAsync(CommandType.Text, sql, _params); + await _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, sql, _params); return 0; } var identColName = _commonUtils.QuoteSqlName(_identCol.Attribute.Name); var identParam = _commonUtils.AppendParamter(null, $"{_identCol.CsName}99", _identCol.CsType, 0) as OracleParameter; identParam.Direction = ParameterDirection.Output; - await _orm.Ado.ExecuteNonQueryAsync(CommandType.Text, $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}", _params.Concat(new[] { identParam }).ToArray()); + await _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, $"{sql} RETURNING {identColName} INTO {identParam.ParameterName}", _params.Concat(new[] { identParam }).ToArray()); return long.TryParse(string.Concat(identParam.Value), out var trylng) ? trylng : 0; } @@ -142,7 +142,7 @@ namespace FreeSql.Oracle.Curd { //end loop; //end; //"); -// return _orm.Ado.Query(CommandType.Text, sb.ToString(), _params); +// return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params); } public override Task> ExecuteInsertedAsync() { throw new NotImplementedException(); diff --git a/FreeSql/PostgreSQL/Curd/PostgreSQLDelete.cs b/FreeSql/PostgreSQL/Curd/PostgreSQLDelete.cs index 30e91634..e6692912 100644 --- a/FreeSql/PostgreSQL/Curd/PostgreSQLDelete.cs +++ b/FreeSql/PostgreSQL/Curd/PostgreSQLDelete.cs @@ -24,7 +24,7 @@ namespace FreeSql.PostgreSQL.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return _orm.Ado.Query(CommandType.Text, sb.ToString(), _params.ToArray()); + return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params.ToArray()); } async public override Task> ExecuteDeletedAsync() { var sql = this.ToSql(); @@ -39,7 +39,7 @@ namespace FreeSql.PostgreSQL.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return await _orm.Ado.QueryAsync(CommandType.Text, sb.ToString(), _params.ToArray()); + return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params.ToArray()); } } } diff --git a/FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs b/FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs index 2a70df25..8e6ea38c 100644 --- a/FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs +++ b/FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs @@ -18,10 +18,10 @@ namespace FreeSql.PostgreSQL.Curd { var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); if (identCols.Any() == false) { - _orm.Ado.ExecuteNonQuery(CommandType.Text, sql, _params); + _orm.Ado.ExecuteNonQuery(_transaction, CommandType.Text, sql, _params); return 0; } - return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)), _params)), out var trylng) ? trylng : 0; + return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)), _params)), out var trylng) ? trylng : 0; } async public override Task ExecuteIdentityAsync() { var sql = this.ToSql(); @@ -29,10 +29,10 @@ namespace FreeSql.PostgreSQL.Curd { var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); if (identCols.Any() == false) { - await _orm.Ado.ExecuteNonQueryAsync(CommandType.Text, sql, _params); + await _orm.Ado.ExecuteNonQueryAsync(_transaction, CommandType.Text, sql, _params); return 0; } - return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(CommandType.Text, string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)), _params)), out var trylng) ? trylng : 0; + return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)), _params)), out var trylng) ? trylng : 0; } public override List ExecuteInserted() { @@ -48,7 +48,7 @@ namespace FreeSql.PostgreSQL.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return _orm.Ado.Query(CommandType.Text, sb.ToString(), _params); + return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params); } async public override Task> ExecuteInsertedAsync() { var sql = this.ToSql(); @@ -63,7 +63,7 @@ namespace FreeSql.PostgreSQL.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return await _orm.Ado.QueryAsync(CommandType.Text, sb.ToString(), _params); + return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params); } } } diff --git a/FreeSql/PostgreSQL/Curd/PostgreSQLUpdate.cs b/FreeSql/PostgreSQL/Curd/PostgreSQLUpdate.cs index 8ca3c124..2528837b 100644 --- a/FreeSql/PostgreSQL/Curd/PostgreSQLUpdate.cs +++ b/FreeSql/PostgreSQL/Curd/PostgreSQLUpdate.cs @@ -27,7 +27,7 @@ namespace FreeSql.PostgreSQL.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return _orm.Ado.Query(CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); + return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); } async public override Task> ExecuteUpdatedAsync() { var sql = this.ToSql(); @@ -42,7 +42,7 @@ namespace FreeSql.PostgreSQL.Curd { sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); ++colidx; } - return await _orm.Ado.QueryAsync(CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); + return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); } protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { diff --git a/FreeSql/SqlServer/Curd/SqlServerDelete.cs b/FreeSql/SqlServer/Curd/SqlServerDelete.cs index ac69a547..1fb86696 100644 --- a/FreeSql/SqlServer/Curd/SqlServerDelete.cs +++ b/FreeSql/SqlServer/Curd/SqlServerDelete.cs @@ -30,7 +30,7 @@ namespace FreeSql.SqlServer.Curd { sb.Insert(0, sql.Substring(0, validx)); sb.Append(sql.Substring(validx)); - return _orm.Ado.Query(CommandType.Text, sb.ToString(), _params.ToArray()); + return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params.ToArray()); } async public override Task> ExecuteDeletedAsync() { var sql = this.ToSql(); @@ -50,7 +50,7 @@ namespace FreeSql.SqlServer.Curd { sb.Insert(0, sql.Substring(0, validx)); sb.Append(sql.Substring(validx)); - return await _orm.Ado.QueryAsync(CommandType.Text, sb.ToString(), _params.ToArray()); + return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params.ToArray()); } } } diff --git a/FreeSql/SqlServer/Curd/SqlServerInsert.cs b/FreeSql/SqlServer/Curd/SqlServerInsert.cs index 19960411..b928ce39 100644 --- a/FreeSql/SqlServer/Curd/SqlServerInsert.cs +++ b/FreeSql/SqlServer/Curd/SqlServerInsert.cs @@ -16,13 +16,13 @@ namespace FreeSql.SqlServer.Curd { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, string.Concat(sql, "; SELECT SCOPE_IDENTITY();"), _params)), out var trylng) ? trylng : 0; + return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, "; SELECT SCOPE_IDENTITY();"), _params)), out var trylng) ? trylng : 0; } async public override Task ExecuteIdentityAsync() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(CommandType.Text, string.Concat(sql, "; SELECT SCOPE_IDENTITY();"), _params)), out var trylng) ? trylng : 0; + return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, "; SELECT SCOPE_IDENTITY();"), _params)), out var trylng) ? trylng : 0; } public override List ExecuteInserted() { @@ -43,7 +43,7 @@ namespace FreeSql.SqlServer.Curd { sb.Insert(0, sql.Substring(0, validx + 1)); sb.Append(sql.Substring(validx + 1)); - return _orm.Ado.Query(CommandType.Text, sb.ToString(), _params); + return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params); } async public override Task> ExecuteInsertedAsync() { var sql = this.ToSql(); @@ -63,7 +63,7 @@ namespace FreeSql.SqlServer.Curd { sb.Insert(0, sql.Substring(0, validx + 1)); sb.Append(sql.Substring(validx + 1)); - return await _orm.Ado.QueryAsync(CommandType.Text, sb.ToString(), _params); + return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params); } } } diff --git a/FreeSql/SqlServer/Curd/SqlServerUpdate.cs b/FreeSql/SqlServer/Curd/SqlServerUpdate.cs index d1080863..fdfd9b78 100644 --- a/FreeSql/SqlServer/Curd/SqlServerUpdate.cs +++ b/FreeSql/SqlServer/Curd/SqlServerUpdate.cs @@ -33,7 +33,7 @@ namespace FreeSql.SqlServer.Curd { sb.Insert(0, sql.Substring(0, validx)); sb.Append(sql.Substring(validx)); - return _orm.Ado.Query(CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); + return _orm.Ado.Query(_transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); } async public override Task> ExecuteUpdatedAsync() { var sql = this.ToSql(); @@ -53,7 +53,7 @@ namespace FreeSql.SqlServer.Curd { sb.Insert(0, sql.Substring(0, validx)); sb.Append(sql.Substring(validx)); - return await _orm.Ado.QueryAsync(CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); + return await _orm.Ado.QueryAsync(_transaction, CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); } protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { diff --git a/FreeSql/Sqlite/Curd/SqliteInsert.cs b/FreeSql/Sqlite/Curd/SqliteInsert.cs index d1a107a0..d26750c0 100644 --- a/FreeSql/Sqlite/Curd/SqliteInsert.cs +++ b/FreeSql/Sqlite/Curd/SqliteInsert.cs @@ -16,13 +16,13 @@ namespace FreeSql.Sqlite.Curd { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, string.Concat(sql, "; SELECT last_insert_rowid();"), _params)), out var trylng) ? trylng : 0; + return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(_transaction, CommandType.Text, string.Concat(sql, "; SELECT last_insert_rowid();"), _params)), out var trylng) ? trylng : 0; } async public override Task ExecuteIdentityAsync() { var sql = this.ToSql(); if (string.IsNullOrEmpty(sql)) return 0; - return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(CommandType.Text, string.Concat(sql, "; SELECT last_insert_rowid();"), _params)), out var trylng) ? trylng : 0; + return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(_transaction, CommandType.Text, string.Concat(sql, "; SELECT last_insert_rowid();"), _params)), out var trylng) ? trylng : 0; } public override List ExecuteInserted() { diff --git a/readme.md b/readme.md index 358e1431..1c6431b2 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,7 @@ FreeSql 是一个功能强大的 .NETStandard 库,用于对象关系映射程序(O/RM),便于开发人员能够使用 .NETStandard 对象来处理数据库,不必经常编写大部分数据访问代码。支持 .NETCore 2.1+ 或 .NETFramework 4.6.1+。 -| Package Name | NuGet | Downloads | | -|--------------| ------- | ---- | -- | +| Package Name | NuGet | Downloads | +|--------------| ------- | ---- | | FreeSql | [![nuget](https://img.shields.io/nuget/v/FreeSql.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql) | [![stats](https://img.shields.io/nuget/dt/FreeSql.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql?groupby=Version) | | [FreeSql.Repository](https://github.com/2881099/FreeSql/wiki/Repository) | [![nuget](https://img.shields.io/nuget/v/FreeSql.Repository.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.Repository) | [![stats](https://img.shields.io/nuget/dt/FreeSql.Repository.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.Repository?groupby=Version) |