diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml
index 25f23c323..4ccbbef74 100644
--- a/FreeSql/FreeSql.xml
+++ b/FreeSql/FreeSql.xml
@@ -1087,6 +1087,93 @@
+
+
+ 动态创建实体类型
+
+
+
+
+ 配置Class
+
+ 类名
+ 类标记的特性[Table(Name = "xxx")] [Index(xxxx)]
+
+
+
+
+ 获取类型构建器,可作为要构建的Type来引用
+
+
+
+
+ 配置属性
+
+ 属性名称
+ 属性类型
+ 属性标记的特性-支持多个
+
+
+
+
+ 配置属性
+
+ 属性名称
+ 属性类型
+ 该属性是否重写父类属性
+ 属性标记的特性-支持多个
+
+
+
+
+ 配置属性
+
+ 属性名称
+ 属性类型
+ 该属性是否重写父类属性
+ 属性默认值
+ 属性标记的特性-支持多个
+
+
+
+
+ 配置父类
+
+ 父类类型
+
+
+
+
+ Override属性
+
+
+
+
+
+ Emit动态创建出Class - Type
+
+
+
+
+
+ Emit动态创建出Class - Type,不附带获取TableInfo
+
+
+
+
+
+ 首字母小写
+
+
+
+
+
+
+ 首字母大写
+
+
+
+
获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 ""
@@ -5810,6 +5897,28 @@
对象池
+
+
+ 动态构建Class Type
+
+
+
+
+
+ 根据字典,创建 table 对应的实体对象
+
+
+
+
+
+
+
+ 根据实体对象,创建 table 对应的字典
+
+
+
+
+
C#: that >= between && that <= and
diff --git a/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleInsert.cs b/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleInsert.cs
index 4cb4146fd..28b6dd447 100644
--- a/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleInsert.cs
+++ b/Providers/FreeSql.Provider.Custom/Oracle/Curd/CustomOracleInsert.cs
@@ -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 ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999);
+ ///
+ /// 批量插入时,如果有序列 + DbInsertValue 设置,则用这个
+ ///
+ ///
+ public string ToSqlBatchIdentityColumn()
+ {
+ if (_source == null || _source.Any() == false) return null;
+ _identCol = null;
+ var cols = new List();
+ 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();
+ 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");
diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs
index e37b718a8..5bbaa708c 100644
--- a/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs
+++ b/Providers/FreeSql.Provider.Odbc/Oracle/Curd/OdbcOracleInsert.cs
@@ -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 ExecuteInserted() => base.SplitExecuteInserted(_batchValuesLimit > 0 ? _batchValuesLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 999);
+ ///
+ /// 批量插入时,如果有序列 + DbInsertValue 设置,则用这个
+ ///
+ ///
+ public string ToSqlBatchIdentityColumn()
+ {
+ if (_source == null || _source.Any() == false) return null;
+ _identCol = null;
+ var cols = new List();
+ 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();
+ 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");
diff --git a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs
index d559e9c72..da7e1b481 100644
--- a/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs
+++ b/Providers/FreeSql.Provider.Oracle/Curd/OracleInsert.cs
@@ -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();
}