- 忧化 DbFirst Oracle 自动批量插入问题;(2020年方法忘记生效)

This commit is contained in:
2881099
2025-01-14 17:01:08 +08:00
parent 09228ada83
commit d29a0509eb
4 changed files with 264 additions and 3 deletions

View File

@@ -1087,6 +1087,93 @@
</summary>
<returns></returns>
</member>
<member name="T:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder">
<summary>
动态创建实体类型
</summary>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.#ctor(IFreeSql,System.String,System.Attribute[])">
<summary>
配置Class
</summary>
<param name="className">类名</param>
<param name="attributes">类标记的特性[Table(Name = "xxx")] [Index(xxxx)]</param>
<returns></returns>
</member>
<member name="P:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.TypeBuilder">
<summary>
获取类型构建器可作为要构建的Type来引用
</summary>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.Property(System.String,System.Type,System.Attribute[])">
<summary>
配置属性
</summary>
<param name="propertyName">属性名称</param>
<param name="propertyType">属性类型</param>
<param name="attributes">属性标记的特性-支持多个</param>
<returns></returns>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.Property(System.String,System.Type,System.Boolean,System.Attribute[])">
<summary>
配置属性
</summary>
<param name="propertyName">属性名称</param>
<param name="propertyType">属性类型</param>
<param name="isOverride">该属性是否重写父类属性</param>
<param name="attributes">属性标记的特性-支持多个</param>
<returns></returns>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.Property(System.String,System.Type,System.Boolean,System.Object,System.Attribute[])">
<summary>
配置属性
</summary>
<param name="propertyName">属性名称</param>
<param name="propertyType">属性类型</param>
<param name="isOverride">该属性是否重写父类属性</param>
<param name="defaultValue">属性默认值</param>
<param name="attributes">属性标记的特性-支持多个</param>
<returns></returns>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.Extend(System.Type)">
<summary>
配置父类
</summary>
<param name="superClass">父类类型</param>
<returns></returns>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.OverrideProperty(System.Reflection.Emit.TypeBuilder@,System.Reflection.Emit.MethodBuilder,FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.PropertyMethodEnum,System.String)">
<summary>
Override属性
</summary>
<param name="typeBuilder"></param>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.Build">
<summary>
Emit动态创建出Class - Type
</summary>
<returns></returns>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.BuildJustType">
<summary>
Emit动态创建出Class - Type不附带获取TableInfo
</summary>
<returns></returns>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.FirstCharToLower(System.String)">
<summary>
首字母小写
</summary>
<param name="input"></param>
<returns></returns>
</member>
<member name="M:FreeSql.Extensions.DynamicEntity.DynamicCompileBuilder.FirstCharToUpper(System.String)">
<summary>
首字母大写
</summary>
<param name="input"></param>
<returns></returns>
</member>
<member name="M:FreeSql.Extensions.EntityUtil.EntityUtilExtensions.GetEntityKeyString(IFreeSql,System.Type,System.Object,System.Boolean,System.String)">
<summary>
获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 ""
@@ -5810,6 +5897,28 @@
对象池
</summary>
</member>
<member name="M:FreeSqlGlobalDynamicEntityExtensions.DynamicEntity(FreeSql.ICodeFirst,System.String,System.Attribute[])">
<summary>
动态构建Class Type
</summary>
<returns></returns>
</member>
<member name="M:FreeSqlGlobalDynamicEntityExtensions.CreateInstance(FreeSql.Internal.Model.TableInfo,System.Collections.Generic.Dictionary{System.String,System.Object})">
<summary>
根据字典,创建 table 对应的实体对象
</summary>
<param name="table"></param>
<param name="dict"></param>
<returns></returns>
</member>
<member name="M:FreeSqlGlobalDynamicEntityExtensions.CreateDictionary(FreeSql.Internal.Model.TableInfo,System.Object)">
<summary>
根据实体对象,创建 table 对应的字典
</summary>
<param name="table"></param>
<param name="instance"></param>
<returns></returns>
</member>
<member name="M:FreeSqlGlobalExpressionCallExtensions.Between(System.DateTime,System.DateTime,System.DateTime)">
<summary>
C# that >= between &amp;&amp; that &lt;= and<para></para>

View File

@@ -23,9 +23,85 @@ namespace FreeSql.Custom.Oracle
public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999);
public override List<T1> ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999);
/// <summary>
/// 批量插入时,如果有序列 + DbInsertValue 设置,则用这个
/// </summary>
/// <returns></returns>
public string ToSqlBatchIdentityColumn()
{
if (_source == null || _source.Any() == false) return null;
_identCol = null;
var cols = new List<ColumnInfo>();
foreach (var col in _table.Columns.Values)
{
if (col.Attribute.IsIdentity) _identCol = col;
if (col.Attribute.IsIdentity && _insertIdentity == false && string.IsNullOrEmpty(col.DbInsertValue)) continue;
if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue;
cols.Add(col);
}
var sb = new StringBuilder();
var tmpsb = new StringBuilder();
sb.Append("INSERT INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append("(");
var colidx = 0;
foreach (var col in cols)
{
if (colidx > 0)
{
sb.Append(", ");
tmpsb.Append(", ");
}
var colname = _commonUtils.QuoteSqlName(col.Attribute.Name);
sb.Append(colname);
tmpsb.Append(col.Attribute.IsIdentity && !string.IsNullOrEmpty(col.DbInsertValue) ? col.DbInsertValue : colname);
++colidx;
}
sb.Append(") ").Append("\r\nSELECT ").Append(tmpsb.ToString()).Append(" FROM ( \r\n");
tmpsb.Clear();
_params = _noneParameter ? new DbParameter[0] : new DbParameter[colidx * _source.Count];
var specialParams = new List<DbParameter>();
var didx = 0;
foreach (var d in _source)
{
if (didx > 0) sb.Append(" \r\nUNION ALL\r\n ");
sb.Append(" SELECT ");
var colidx2 = 0;
foreach (var col in cols)
{
if (col.Attribute.IsIdentity && !string.IsNullOrEmpty(col.DbInsertValue)) continue;
if (colidx2 > 0) sb.Append(", ");
if (string.IsNullOrEmpty(col.DbInsertValue) == false && _ignoreInsertValueSql.ContainsKey(col.Attribute.Name) == false)
sb.Append(col.DbInsertValue);
else
{
object val = col.GetDbValue(d);
if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384
var colsql = _noneParameter ? _commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col, col.Attribute.MapType, val) :
_commonUtils.QuoteWriteParamterAdapter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"));
sb.Append(_commonUtils.RewriteColumn(col, colsql));
if (_noneParameter == false)
_params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col, col.Attribute.MapType, val);
}
if (didx == 0) sb.Append(" as ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name));
++colidx2;
}
sb.Append(" FROM dual ");
++didx;
}
sb.Append(" )");
if (_noneParameter && specialParams.Any()) _params = specialParams.ToArray();
return sb.ToString();
}
public override string ToSql()
{
if (_source == null || _source.Any() == false) return null;
if (_source.Count > 1 && _table.Columns.Values.Any(col => col.Attribute.IsIdentity && !string.IsNullOrEmpty(col.DbInsertValue)))
return ToSqlBatchIdentityColumn();
var sb = new StringBuilder();
sb.Append("INSERT ");
if (_source.Count > 1) sb.Append("ALL");

View File

@@ -23,9 +23,85 @@ namespace FreeSql.Odbc.Oracle
public override long ExecuteIdentity() => base.SplitExecuteIdentity(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999);
public override List<T1> ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999);
/// <summary>
/// 批量插入时,如果有序列 + DbInsertValue 设置,则用这个
/// </summary>
/// <returns></returns>
public string ToSqlBatchIdentityColumn()
{
if (_source == null || _source.Any() == false) return null;
_identCol = null;
var cols = new List<ColumnInfo>();
foreach (var col in _table.Columns.Values)
{
if (col.Attribute.IsIdentity) _identCol = col;
if (col.Attribute.IsIdentity && _insertIdentity == false && string.IsNullOrEmpty(col.DbInsertValue)) continue;
if (col.Attribute.IsIdentity == false && _ignore.ContainsKey(col.Attribute.Name)) continue;
cols.Add(col);
}
var sb = new StringBuilder();
var tmpsb = new StringBuilder();
sb.Append("INSERT INTO ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append("(");
var colidx = 0;
foreach (var col in cols)
{
if (colidx > 0)
{
sb.Append(", ");
tmpsb.Append(", ");
}
var colname = _commonUtils.QuoteSqlName(col.Attribute.Name);
sb.Append(colname);
tmpsb.Append(col.Attribute.IsIdentity && !string.IsNullOrEmpty(col.DbInsertValue) ? col.DbInsertValue : colname);
++colidx;
}
sb.Append(") ").Append("\r\nSELECT ").Append(tmpsb.ToString()).Append(" FROM ( \r\n");
tmpsb.Clear();
_params = _noneParameter ? new DbParameter[0] : new DbParameter[colidx * _source.Count];
var specialParams = new List<DbParameter>();
var didx = 0;
foreach (var d in _source)
{
if (didx > 0) sb.Append(" \r\nUNION ALL\r\n ");
sb.Append(" SELECT ");
var colidx2 = 0;
foreach (var col in cols)
{
if (col.Attribute.IsIdentity && !string.IsNullOrEmpty(col.DbInsertValue)) continue;
if (colidx2 > 0) sb.Append(", ");
if (string.IsNullOrEmpty(col.DbInsertValue) == false && _ignoreInsertValueSql.ContainsKey(col.Attribute.Name) == false)
sb.Append(col.DbInsertValue);
else
{
object val = col.GetDbValue(d);
if (val == null && col.Attribute.IsNullable == false) val = col.CsType == typeof(string) ? "" : Utils.GetDataReaderValue(col.CsType.NullableTypeOrThis(), null);//#384
var colsql = _noneParameter ? _commonUtils.GetNoneParamaterSqlValue(specialParams, _noneParameterFlag, col, col.Attribute.MapType, val) :
_commonUtils.QuoteWriteParamterAdapter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"{col.CsName}_{didx}"));
sb.Append(_commonUtils.RewriteColumn(col, colsql));
if (_noneParameter == false)
_params[didx * colidx + colidx2] = _commonUtils.AppendParamter(null, $"{col.CsName}_{didx}", col, col.Attribute.MapType, val);
}
if (didx == 0) sb.Append(" as ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name));
++colidx2;
}
sb.Append(" FROM dual ");
++didx;
}
sb.Append(" )");
if (_noneParameter && specialParams.Any()) _params = specialParams.ToArray();
return sb.ToString();
}
public override string ToSql()
{
if (_source == null || _source.Any() == false) return null;
if (_source.Count > 1 && _table.Columns.Values.Any(col => col.Attribute.IsIdentity && !string.IsNullOrEmpty(col.DbInsertValue)))
return ToSqlBatchIdentityColumn();
var sb = new StringBuilder();
sb.Append("INSERT ");
if (_source.Count > 1) sb.Append("ALL");

View File

@@ -66,7 +66,7 @@ namespace FreeSql.Oracle.Curd
tmpsb.Append(col.Attribute.IsIdentity && !string.IsNullOrEmpty(col.DbInsertValue) ? col.DbInsertValue : colname);
++colidx;
}
sb.Append(") ").Append("\r\nSELECT ").Append(tmpsb.ToString()).Append(" FROM \r\n(\r\n");
sb.Append(") ").Append("\r\nSELECT ").Append(tmpsb.ToString()).Append(" FROM ( \r\n");
tmpsb.Clear();
_params = _noneParameter ? new DbParameter[0] : new DbParameter[colidx * _source.Count];
@@ -74,7 +74,7 @@ namespace FreeSql.Oracle.Curd
var didx = 0;
foreach (var d in _source)
{
if (didx > 0) sb.Append("\r\n UNION ALL\r\n ");
if (didx > 0) sb.Append(" \r\nUNION ALL\r\n ");
sb.Append(" SELECT ");
var colidx2 = 0;
foreach (var col in cols)
@@ -100,7 +100,7 @@ namespace FreeSql.Oracle.Curd
sb.Append(" FROM dual ");
++didx;
}
sb.Append(")");
sb.Append(" )");
if (_noneParameter && specialParams.Any()) _params = specialParams.ToArray();
return sb.ToString();
}