重写批量修改,去除插入和修改事务,修改插入数据的限制默认值为int.MaxValue,自增字段直接返回0

This commit is contained in:
chenbo
2021-11-30 15:02:21 +08:00
parent 846c180191
commit ae0f2e9d0d
14 changed files with 869 additions and 281 deletions

View File

@ -22,20 +22,12 @@ namespace FreeSql.ClickHouse.Curd
internal StringBuilder InternalSbSet => _set;
internal StringBuilder InternalSbSetIncr => _setIncr;
internal Dictionary<string, bool> InternalIgnore => _ignore;
public override string ToSql()
{
var sql = base.ToSql();
sql = sql.Remove(0, 6).Insert(0, "ALTER TABLE");
var index = sql.IndexOf(" SET ");
sql = sql.Remove(index, 5).Insert(index, " UPDATE ");
return sql;
}
internal void InternalResetSource(List<T1> source) => _source = source;
internal string InternalWhereCaseSource(string CsName, Func<string, string> thenValue) => WhereCaseSource(CsName, thenValue);
internal void InternalToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col) => ToSqlCaseWhenEnd(sb, col);
public override int ExecuteAffrows() => base.SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000);
public override List<T1> ExecuteUpdated() => base.SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000);
public override int ExecuteAffrows() => SplitExecuteAffrows(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000);
public override List<T1> ExecuteUpdated() => SplitExecuteUpdated(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000);
protected override List<T1> RawExecuteUpdated() => throw new NotImplementedException("FreeSql.ClickHouse.Custom 未实现该功能 未实现该功能");
protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys)
{
@ -72,15 +64,315 @@ namespace FreeSql.ClickHouse.Curd
}
sb.Append(")");
}
protected override void ToSqlCaseWhenEnd(StringBuilder sb, ColumnInfo col)
public override string ToSql()
{
sb.Insert(sb.Length - 4, $" ELSE {_commonUtils.QuoteSqlName(col.Attribute.Name)}");
if (_where.Length == 0 && _source.Any() == false) return null;
var sb = new StringBuilder();
sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(TableRuleInvoke())).Append(" UPDATE ");
if (_set.Length > 0)
{ //指定 set 更新
sb.Append(_set.ToString().Substring(2));
}
else if (_source.Count == 1)
{ //保存 Source
_paramsSource.Clear();
var colidx = 0;
foreach (var col in _table.Columns.Values)
{
if (col.Attribute.IsPrimary) continue;
if (_tempPrimarys.Any(a => a.CsName == col.CsName)) continue;
if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && _ignore.ContainsKey(col.Attribute.Name) == false)
{
if (colidx > 0) sb.Append(", ");
sb.Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ");
if (col.Attribute.CanUpdate && string.IsNullOrEmpty(col.DbUpdateValue) == false)
sb.Append(col.DbUpdateValue);
else
{
var val = col.GetDbValue(_source.First());
var colsql = _noneParameter ? _commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col, col.Attribute.MapType, val) :
_commonUtils.QuoteWriteParamterAdapter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"));
sb.Append(_commonUtils.RewriteColumn(col, colsql));
if (_noneParameter == false)
_commonUtils.AppendParamter(_paramsSource, null, col, col.Attribute.MapType, val);
}
++colidx;
}
}
if (colidx == 0) return null;
}
else if (_source.Count > 1)
{ //批量保存 Source
if (_tempPrimarys.Any() == false) return null;
var caseWhen = new StringBuilder();
ToSqlCase(caseWhen, _tempPrimarys);
var cw = $"{caseWhen.ToString()}=";
_paramsSource.Clear();
var colidx = 0;
foreach (var col in _table.Columns.Values)
{
if (col.Attribute.IsPrimary) continue;
if (_tempPrimarys.Any(a => a.CsName == col.CsName)) continue;
if (col.Attribute.IsIdentity == false && col.Attribute.IsVersion == false && _ignore.ContainsKey(col.Attribute.Name) == false)
{
if (colidx > 0) sb.Append(", ");
var columnName = _commonUtils.QuoteSqlName(col.Attribute.Name);
sb.Append(columnName).Append(" = ");
if (col.Attribute.CanUpdate && string.IsNullOrEmpty(col.DbUpdateValue) == false)
sb.Append(col.DbUpdateValue);
else
{
var nulls = 0;
var cwsb = new StringBuilder().Append(" multiIf( ");
foreach (var d in _source)
{
cwsb.Append(cw);
ToSqlWhen(cwsb, _tempPrimarys, d);
cwsb.Append(",");
var val = col.GetDbValue(d);
var colsql = _noneParameter ? _commonUtils.GetNoneParamaterSqlValue(_paramsSource, "u", col, col.Attribute.MapType, val) :
_commonUtils.QuoteWriteParamterAdapter(col.Attribute.MapType, _commonUtils.QuoteParamterName($"p_{_paramsSource.Count}"));
cwsb.Append(_commonUtils.RewriteColumn(col, colsql));
if (_noneParameter == false)
_commonUtils.AppendParamter(_paramsSource, null, col, col.Attribute.MapType, val);
if (val == null || val == DBNull.Value) nulls++;
cwsb.Append(", ");
}
if (nulls == _source.Count) sb.Append("NULL");
else
{
cwsb.Append(columnName).Append(" )");
ToSqlCaseWhenEnd(cwsb, col);
sb.Append(cwsb);
}
cwsb.Clear();
}
++colidx;
}
}
if (colidx == 0) return null;
}
else if (_setIncr.Length == 0)
return null;
if (_setIncr.Length > 0)
sb.Append(_set.Length > 0 ? _setIncr.ToString() : _setIncr.ToString().Substring(2));
if (_source.Any() == false)
{
foreach (var col in _table.Columns.Values)
if (col.Attribute.CanUpdate && string.IsNullOrEmpty(col.DbUpdateValue) == false)
sb.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(col.DbUpdateValue);
}
if (_table.VersionColumn != null)
{
var vcname = _commonUtils.QuoteSqlName(_table.VersionColumn.Attribute.Name);
if (_table.VersionColumn.Attribute.MapType == typeof(byte[]))
{
_updateVersionValue = Utils.GuidToBytes(Guid.NewGuid());
sb.Append(", ").Append(vcname).Append(" = ").Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "uv", _table.VersionColumn, _table.VersionColumn.Attribute.MapType, _updateVersionValue));
}
else
sb.Append(", ").Append(vcname).Append(" = ").Append(_commonUtils.IsNull(vcname, 0)).Append(" + 1");
}
sb.Append(" \r\nWHERE ");
if (_source.Any())
{
if (_tempPrimarys.Any() == false) throw new ArgumentException($"{_table.Type.DisplayCsharp()} 没有定义主键,无法使用 SetSource请尝试 SetDto");
sb.Append('(').Append(_commonUtils.WhereItems(_tempPrimarys, "", _source)).Append(')');
}
if (_where.Length > 0)
sb.Append(_source.Any() ? _where.ToString() : _where.ToString().Substring(5));
if (_whereGlobalFilter.Any())
{
var globalFilterCondi = _commonExpression.GetWhereCascadeSql(new SelectTableInfo { Table = _table }, _whereGlobalFilter, false);
if (string.IsNullOrEmpty(globalFilterCondi) == false)
sb.Append(" AND ").Append(globalFilterCondi);
}
if (_table.VersionColumn != null)
{
var versionCondi = WhereCaseSource(_table.VersionColumn.CsName, sqlval => sqlval);
if (string.IsNullOrEmpty(versionCondi) == false)
sb.Append(" AND ").Append(versionCondi);
}
_interceptSql?.Invoke(sb);
return sb.ToString();
}
protected override int SplitExecuteAffrows(int valuesLimit, int parameterLimit)
{
var ss = base.SplitSource(valuesLimit, parameterLimit);
var ret = 0;
if (ss.Length <= 1)
{
if (_source?.Any() == true) _batchProgress?.Invoke(new BatchProgressStatus<T1>(_source, 1, 1));
ret = this.RawExecuteAffrows();
ClearData();
return ret;
}
var before = new Aop.TraceBeforeEventArgs("SplitExecuteAffrows", null);
_orm.Aop.TraceBeforeHandler?.Invoke(this, before);
Exception exception = null;
try
{
for (var a = 0; a < ss.Length; a++)
{
_source = ss[a];
_batchProgress?.Invoke(new BatchProgressStatus<T1>(_source, a + 1, ss.Length));
ret += this.RawExecuteAffrows();
}
}
catch (Exception ex)
{
exception = ex;
throw;
}
finally
{
var after = new Aop.TraceAfterEventArgs(before, null, exception);
_orm.Aop.TraceAfterHandler?.Invoke(this, after);
}
ClearData();
return ret;
}
protected override List<T1> SplitExecuteUpdated(int valuesLimit, int parameterLimit)
{
var ss = SplitSource(valuesLimit, parameterLimit);
var ret = new List<T1>();
if (ss.Length <= 1)
{
if (_source?.Any() == true) _batchProgress?.Invoke(new BatchProgressStatus<T1>(_source, 1, 1));
ret = this.RawExecuteUpdated();
ClearData();
return ret;
}
var before = new Aop.TraceBeforeEventArgs("SplitExecuteUpdated", null);
_orm.Aop.TraceBeforeHandler?.Invoke(this, before);
Exception exception = null;
try
{
for (var a = 0; a < ss.Length; a++)
{
_source = ss[a];
_batchProgress?.Invoke(new BatchProgressStatus<T1>(_source, a + 1, ss.Length));
ret.AddRange(this.RawExecuteUpdated());
}
}
catch (Exception ex)
{
exception = ex;
throw;
}
finally
{
var after = new Aop.TraceAfterEventArgs(before, null, exception);
_orm.Aop.TraceAfterHandler?.Invoke(this, after);
}
ClearData();
return ret;
}
#if net40
#else
public override Task<int> ExecuteAffrowsAsync(CancellationToken cancellationToken = default) => base.SplitExecuteAffrowsAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken);
public override Task<List<T1>> ExecuteUpdatedAsync(CancellationToken cancellationToken = default) => base.SplitExecuteUpdatedAsync(_batchRowsLimit > 0 ? _batchRowsLimit : 500, _batchParameterLimit > 0 ? _batchParameterLimit : 3000, cancellationToken);
protected override Task<List<T1>> RawExecuteUpdatedAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException("FreeSql.ClickHouse.Custom 未实现该功能 未实现该功能");
async protected override Task<int> SplitExecuteAffrowsAsync(int valuesLimit, int parameterLimit, CancellationToken cancellationToken = default)
{
var ss = SplitSource(valuesLimit, parameterLimit);
var ret = 0;
if (ss.Length <= 1)
{
if (_source?.Any() == true) _batchProgress?.Invoke(new BatchProgressStatus<T1>(_source, 1, 1));
ret = await this.RawExecuteAffrowsAsync(cancellationToken);
ClearData();
return ret;
}
var before = new Aop.TraceBeforeEventArgs("SplitExecuteAffrowsAsync", null);
_orm.Aop.TraceBeforeHandler?.Invoke(this, before);
Exception exception = null;
try
{
for (var a = 0; a < ss.Length; a++)
{
_source = ss[a];
_batchProgress?.Invoke(new BatchProgressStatus<T1>(_source, a + 1, ss.Length));
ret += await this.RawExecuteAffrowsAsync(cancellationToken);
}
}
catch (Exception ex)
{
exception = ex;
throw;
}
finally
{
var after = new Aop.TraceAfterEventArgs(before, null, exception);
_orm.Aop.TraceAfterHandler?.Invoke(this, after);
}
ClearData();
return ret;
}
async protected override Task<List<T1>> SplitExecuteUpdatedAsync(int valuesLimit, int parameterLimit, CancellationToken cancellationToken = default)
{
var ss = SplitSource(valuesLimit, parameterLimit);
var ret = new List<T1>();
if (ss.Length <= 1)
{
if (_source?.Any() == true) _batchProgress?.Invoke(new BatchProgressStatus<T1>(_source, 1, 1));
ret = await this.RawExecuteUpdatedAsync(cancellationToken);
ClearData();
return ret;
}
var before = new Aop.TraceBeforeEventArgs("SplitExecuteUpdatedAsync", null);
_orm.Aop.TraceBeforeHandler?.Invoke(this, before);
Exception exception = null;
try
{
for (var a = 0; a < ss.Length; a++)
{
_source = ss[a];
_batchProgress?.Invoke(new BatchProgressStatus<T1>(_source, a + 1, ss.Length));
ret.AddRange(await this.RawExecuteUpdatedAsync(cancellationToken));
}
}
catch (Exception ex)
{
exception = ex;
throw;
}
finally
{
var after = new Aop.TraceAfterEventArgs(before, null, exception);
_orm.Aop.TraceAfterHandler?.Invoke(this, after);
}
ClearData();
return ret;
}
#endif
}
}