From f861c9da6ea5763b0cec24aee733c4f2c24c48df Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 27 Mar 2025 23:47:30 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20MySql8.0.30=20?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E4=BD=BF=E7=94=A8=20ExecuteInserted=20?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B#2001?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 2 + FreeSql/FreeSql.xml | 118 ++---------------- FreeSql/Interface/Curd/IInsert.cs | 7 +- .../Internal/CommonProvider/InsertProvider.cs | 12 +- .../CommonProvider/InsertProviderAsync.cs | 12 +- FreeSql/Internal/UtilsExpressionTree.cs | 2 + .../MySql/Curd/CustomMySqlInsert.cs | 57 +++++++-- .../Curd/MySqlInsert.cs | 53 ++++++-- .../MySql/Curd/OdbcMySqlInsert.cs | 57 +++++++-- 9 files changed, 169 insertions(+), 151 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index a3aa4e058..7f38c8d4a 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -621,6 +621,8 @@ namespace base_entity BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion + fsql.Insert(new User1()).ExecuteInserted(); + fsql.InsertOrUpdate().SetSource(new AppInfoEntity { AppID = "03DN8CW8", AppName = "app_01" }).ExecuteAffrows(); var repo2211 = fsql.GetRepository(); diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 6e6fddabc..1b3cb2445 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1087,93 +1087,6 @@ - - - 动态创建实体类型 - - - - - 配置Class - - 类名 - 类标记的特性[Table(Name = "xxx")] [Index(xxxx)] - - - - - 获取类型构建器,可作为要构建的Type来引用 - - - - - 配置属性 - - 属性名称 - 属性类型 - 属性标记的特性-支持多个 - - - - - 配置属性 - - 属性名称 - 属性类型 - 该属性是否重写父类属性 - 属性标记的特性-支持多个 - - - - - 配置属性 - - 属性名称 - 属性类型 - 该属性是否重写父类属性 - 属性默认值 - 属性标记的特性-支持多个 - - - - - 配置父类 - - 父类类型 - - - - - Override属性 - - - - - - Emit动态创建出Class - Type - - - - - - Emit动态创建出Class - Type,不附带获取TableInfo - - - - - - 首字母小写 - - - - - - - 首字母大写 - - - - 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 "" @@ -1945,7 +1858,7 @@ 执行SQL语句,返回插入后的记录 - 注意:此方法只有 Postgresql/SqlServer/Maridb/Firebird/DuckDB/人大金仓 有效果 + 注意:此方法只有 Postgresql/SqlServer/MySql8.0.30+/Maridb/Firebird/DuckDB/人大金仓 有效果 @@ -1958,6 +1871,13 @@ + + + 执行SQL语句,返回插入后的记录 + 注意:此方法只有 Postgresql/SqlServer/MySql8.0.30+/Maridb/Firebird/DuckDB/人大金仓 有效果 + + + 指定事务对象 @@ -5955,28 +5875,6 @@ 对象池 - - - 动态构建Class Type - - - - - - 根据字典,创建 table 对应的实体对象 - - - - - - - - 根据实体对象,创建 table 对应的字典 - - - - - C#: that >= between && that <= and diff --git a/FreeSql/Interface/Curd/IInsert.cs b/FreeSql/Interface/Curd/IInsert.cs index a3eef860a..0b3be6998 100644 --- a/FreeSql/Interface/Curd/IInsert.cs +++ b/FreeSql/Interface/Curd/IInsert.cs @@ -156,7 +156,7 @@ namespace FreeSql long ExecuteIdentity(); /// /// 执行SQL语句,返回插入后的记录 - /// 注意:此方法只有 Postgresql/SqlServer/Maridb/Firebird/DuckDB/人大金仓 有效果 + /// 注意:此方法只有 Postgresql/SqlServer/MySql8.0.30+/Maridb/Firebird/DuckDB/人大金仓 有效果 /// /// List ExecuteInserted(); @@ -174,6 +174,11 @@ namespace FreeSql #else Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default); Task ExecuteIdentityAsync(CancellationToken cancellationToken = default); + /// + /// 执行SQL语句,返回插入后的记录 + /// 注意:此方法只有 Postgresql/SqlServer/MySql8.0.30+/Maridb/Firebird/DuckDB/人大金仓 有效果 + /// + /// Task> ExecuteInsertedAsync(CancellationToken cancellationToken = default); #endif } diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 1146dee7f..5c32157ee 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -431,7 +431,7 @@ namespace FreeSql.Internal.CommonProvider if (ss.Length == 1) { _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); - ret = this.RawExecuteInserted(); + ret = this.InternalExecuteInserted(); ClearData(); return ret; } @@ -452,7 +452,7 @@ namespace FreeSql.Internal.CommonProvider { _source = ss[a]; _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret.AddRange(this.RawExecuteInserted()); + ret.AddRange(this.InternalExecuteInserted()); } } else @@ -469,7 +469,7 @@ namespace FreeSql.Internal.CommonProvider { _source = ss[a]; _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret.AddRange(this.RawExecuteInserted()); + ret.AddRange(this.InternalExecuteInserted()); } _transaction.Commit(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, CoreErrorStrings.Commit, null)); @@ -525,6 +525,12 @@ namespace FreeSql.Internal.CommonProvider protected abstract long RawExecuteIdentity(); protected abstract List RawExecuteInserted(); + private List InternalExecuteInserted() + { + var ret = RawExecuteInserted(); + if (_table.TypeLazySetOrm != null) ret.ForEach(item => _table.TypeLazySetOrm.Invoke(item, new object[] { _orm })); + return ret; + } public abstract int ExecuteAffrows(); public abstract long ExecuteIdentity(); diff --git a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs index d997d3676..a0f642f6d 100644 --- a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs @@ -189,7 +189,7 @@ namespace FreeSql.Internal.CommonProvider if (ss.Length == 1) { _batchProgress?.Invoke(new BatchProgressStatus(_source, 1, 1)); - ret = await this.RawExecuteInsertedAsync(cancellationToken); + ret = await this.InternalExecuteInsertedAsync(cancellationToken); ClearData(); return ret; } @@ -210,7 +210,7 @@ namespace FreeSql.Internal.CommonProvider { _source = ss[a]; _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret.AddRange(await this.RawExecuteInsertedAsync(cancellationToken)); + ret.AddRange(await this.InternalExecuteInsertedAsync(cancellationToken)); } } else @@ -227,7 +227,7 @@ namespace FreeSql.Internal.CommonProvider { _source = ss[a]; _batchProgress?.Invoke(new BatchProgressStatus(_source, a + 1, ss.Length)); - ret.AddRange(await this.RawExecuteInsertedAsync(cancellationToken)); + ret.AddRange(await this.InternalExecuteInsertedAsync(cancellationToken)); } _transaction.Commit(); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, CoreErrorStrings.Commit, null)); @@ -282,6 +282,12 @@ namespace FreeSql.Internal.CommonProvider protected abstract Task RawExecuteIdentityAsync(CancellationToken cancellationToken = default); protected abstract Task> RawExecuteInsertedAsync(CancellationToken cancellationToken = default); + async private Task> InternalExecuteInsertedAsync(CancellationToken cancellationToken = default) + { + var ret = await RawExecuteInsertedAsync(cancellationToken); + if (_table.TypeLazySetOrm != null) ret.ForEach(item => _table.TypeLazySetOrm.Invoke(item, new object[] { _orm })); + return ret; + } public abstract Task ExecuteAffrowsAsync(CancellationToken cancellationToken = default); public abstract Task ExecuteIdentityAsync(CancellationToken cancellationToken = default); diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 81a14f8ef..f7850b2eb 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -1752,6 +1752,8 @@ namespace FreeSql.Internal } return dr.GetValue(index); } + public static object ExecuteReaderToClass(string flagStr, Type typeOrg, int[] indexes, DbDataReader row, int dataIndex, CommonUtils _commonUtils) => + ExecuteArrayRowReadClassOrTuple(flagStr, typeOrg, indexes, row, dataIndex, _commonUtils)?.Value; internal static RowInfo ExecuteArrayRowReadClassOrTuple(string flagStr, Type typeOrg, int[] indexes, DbDataReader row, int dataIndex, CommonUtils _commonUtils) { if (string.IsNullOrEmpty(flagStr)) flagStr = "all"; diff --git a/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlInsert.cs b/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlInsert.cs index df5f24dfd..a6902fbec 100644 --- a/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlInsert.cs +++ b/Providers/FreeSql.Provider.Custom/MySql/Curd/CustomMySqlInsert.cs @@ -89,12 +89,25 @@ namespace FreeSql.Custom.MySql sb.Append(sql).Append(" RETURNING "); var colidx = 0; - foreach (var col in _table.Columns.Values) + var propidx = 0; + var props = _table.Type.GetPropertiesDictIgnoreCase(); + var indexes = new int[props.Count]; + var sbflag = new StringBuilder().Append("insertedQuery"); + foreach (var prop in props) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; + if (_table.ColumnsByCs.TryGetValue(prop.Key, out var col)) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))); + sbflag.Append(col.Attribute.Name).Append(":").Append(colidx).Append(","); + indexes[propidx] = colidx; + ++colidx; + } + else + indexes[propidx] = -1; + ++propidx; } + var flag = sbflag.ToString(); sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); @@ -102,12 +115,15 @@ namespace FreeSql.Custom.MySql Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => + { + ret.Add((T1)Utils.ExecuteReaderToClass(flag, _table.TypeLazy ?? _table.Type, indexes, fetch.Object, 0, _commonUtils)); + }, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -169,12 +185,25 @@ namespace FreeSql.Custom.MySql sb.Append(sql).Append(" RETURNING "); var colidx = 0; - foreach (var col in _table.Columns.Values) + var propidx = 0; + var props = _table.Type.GetPropertiesDictIgnoreCase(); + var indexes = new int[props.Count]; + var sbflag = new StringBuilder().Append("insertedQuery"); + foreach (var prop in props) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; + if (_table.ColumnsByCs.TryGetValue(prop.Key, out var col)) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))); + sbflag.Append(col.Attribute.Name).Append(":").Append(colidx).Append(","); + indexes[propidx] = colidx; + ++colidx; + } + else + indexes[propidx] = -1; + ++propidx; } + var flag = sbflag.ToString(); sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); @@ -182,12 +211,16 @@ namespace FreeSql.Custom.MySql Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => + { + ret.Add((T1)Utils.ExecuteReaderToClass(flag, _table.TypeLazy ?? _table.Type, indexes, fetch.Object, 0, _commonUtils)); + return Task.FromResult(false); + }, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { diff --git a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs index 146b3e57c..33e358e92 100644 --- a/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs +++ b/Providers/FreeSql.Provider.MySql/Curd/MySqlInsert.cs @@ -77,12 +77,25 @@ namespace FreeSql.MySql.Curd sb.Append(sql).Append(" RETURNING "); var colidx = 0; - foreach (var col in _table.Columns.Values) + var propidx = 0; + var props = _table.Type.GetPropertiesDictIgnoreCase(); //与 ExecuteArrayRowReadClassOrTuple 顺序同步 + var indexes = new int[props.Count]; + var sbflag = new StringBuilder().Append("insertedQuery"); + foreach (var prop in props) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; + if (_table.ColumnsByCs.TryGetValue(prop.Key, out var col)) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))); + sbflag.Append(col.Attribute.Name).Append(":").Append(colidx).Append(","); + indexes[propidx] = colidx; + ++colidx; + } + else + indexes[propidx] = -1; + ++propidx; } + var flag = sbflag.ToString(); sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); @@ -90,7 +103,10 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => + { + ret.Add((T1)Utils.ExecuteReaderToClass(flag, _table.TypeLazy ?? _table.Type, indexes, fetch.Object, 0, _commonUtils)); + }, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { @@ -146,12 +162,25 @@ namespace FreeSql.MySql.Curd sb.Append(sql).Append(" RETURNING "); var colidx = 0; - foreach (var col in _table.Columns.Values) + var propidx = 0; + var props = _table.Type.GetPropertiesDictIgnoreCase(); + var indexes = new int[props.Count]; + var sbflag = new StringBuilder().Append("insertedQuery"); + foreach (var prop in props) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; + if (_table.ColumnsByCs.TryGetValue(prop.Key, out var col)) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))); + sbflag.Append(col.Attribute.Name).Append(":").Append(colidx).Append(","); + indexes[propidx] = colidx; + ++colidx; + } + else + indexes[propidx] = -1; + ++propidx; } + var flag = sbflag.ToString(); sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); @@ -159,7 +188,11 @@ namespace FreeSql.MySql.Curd Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => + { + ret.Add((T1)Utils.ExecuteReaderToClass(flag, _table.TypeLazy ?? _table.Type, indexes, fetch.Object, 0, _commonUtils)); + return Task.FromResult(false); + }, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs index e9c022731..703071dbd 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs @@ -89,12 +89,25 @@ namespace FreeSql.Odbc.MySql sb.Append(sql).Append(" RETURNING "); var colidx = 0; - foreach (var col in _table.Columns.Values) + var propidx = 0; + var props = _table.Type.GetPropertiesDictIgnoreCase(); + var indexes = new int[props.Count]; + var sbflag = new StringBuilder().Append("insertedQuery"); + foreach (var prop in props) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; + if (_table.ColumnsByCs.TryGetValue(prop.Key, out var col)) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))); + sbflag.Append(col.Attribute.Name).Append(":").Append(colidx).Append(","); + indexes[propidx] = colidx; + ++colidx; + } + else + indexes[propidx] = -1; + ++propidx; } + var flag = sbflag.ToString(); sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); @@ -102,12 +115,15 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = _orm.Ado.Query(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params); + _orm.Ado.ExecuteReader(_connection, _transaction, fetch => + { + ret.Add((T1)Utils.ExecuteReaderToClass(flag, _table.TypeLazy ?? _table.Type, indexes, fetch.Object, 0, _commonUtils)); + }, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { exception = ex; - throw ex; + throw; } finally { @@ -169,12 +185,25 @@ namespace FreeSql.Odbc.MySql sb.Append(sql).Append(" RETURNING "); var colidx = 0; - foreach (var col in _table.Columns.Values) + var propidx = 0; + var props = _table.Type.GetPropertiesDictIgnoreCase(); + var indexes = new int[props.Count]; + var sbflag = new StringBuilder().Append("insertedQuery"); + foreach (var prop in props) { - if (colidx > 0) sb.Append(", "); - sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); - ++colidx; + if (_table.ColumnsByCs.TryGetValue(prop.Key, out var col)) + { + if (colidx > 0) sb.Append(", "); + sb.Append(_commonUtils.RereadColumn(col, _commonUtils.QuoteSqlName(col.Attribute.Name))); + sbflag.Append(col.Attribute.Name).Append(":").Append(colidx).Append(","); + indexes[propidx] = colidx; + ++colidx; + } + else + indexes[propidx] = -1; + ++propidx; } + var flag = sbflag.ToString(); sql = sb.ToString(); var before = new Aop.CurdBeforeEventArgs(_table.Type, _table, Aop.CurdType.Insert, sql, _params); _orm.Aop.CurdBeforeHandler?.Invoke(this, before); @@ -182,12 +211,16 @@ namespace FreeSql.Odbc.MySql Exception exception = null; try { - ret = await _orm.Ado.QueryAsync(_table.TypeLazy ?? _table.Type, _connection, _transaction, CommandType.Text, sql, _commandTimeout, _params, cancellationToken); + await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => + { + ret.Add((T1)Utils.ExecuteReaderToClass(flag, _table.TypeLazy ?? _table.Type, indexes, fetch.Object, 0, _commonUtils)); + return Task.FromResult(false); + }, CommandType.Text, sql, _commandTimeout, _params); } catch (Exception ex) { exception = ex; - throw ex; + throw; } finally {