- 增加 IInsertOrUpdate BatchOptions 选项;

This commit is contained in:
2881099 2023-08-22 14:14:20 +08:00
parent c228332c4c
commit 0a048567b8
2 changed files with 92 additions and 19 deletions

View File

@ -96,6 +96,16 @@ namespace FreeSql
/// <returns></returns> /// <returns></returns>
IInsertOrUpdate<T1> UpdateSet<TMember>(Expression<Func<T1, T1, TMember>> exp); IInsertOrUpdate<T1> UpdateSet<TMember>(Expression<Func<T1, T1, TMember>> exp);
/// <summary>
/// 批量执行选项设置,一般不需要使用该方法<para></para>
/// 各数据库 rows 限制不一样默认设置200<para></para>
/// 若没有事务传入,内部(默认)会自动开启新事务,保证拆包执行的完整性。
/// </summary>
/// <param name="rowsLimit">指定根据 rows 上限数量拆分执行</param>
/// <param name="autoTransaction">是否自动开启事务</param>
/// <returns></returns>
IInsertOrUpdate<T1> BatchOptions(int rowsLimit, bool autoTransaction = true);
/// <summary> /// <summary>
/// 设置表名规则,可用于分库/分表参数1默认表名返回值新表名 /// 设置表名规则,可用于分库/分表参数1默认表名返回值新表名
/// </summary> /// </summary>

View File

@ -27,6 +27,8 @@ namespace FreeSql.Internal.CommonProvider
public TableInfo _table; public TableInfo _table;
public ColumnInfo[] _tempPrimarys; public ColumnInfo[] _tempPrimarys;
public Func<string, string> _tableRule; public Func<string, string> _tableRule;
public int _batchValuesLimit;
public bool _batchAutoTransaction = true;
public DbParameter[] _params; public DbParameter[] _params;
public DbTransaction _transaction; public DbTransaction _transaction;
public DbConnection _connection; public DbConnection _connection;
@ -56,7 +58,13 @@ namespace FreeSql.Internal.CommonProvider
{ {
_source.Clear(); _source.Clear();
_sourceSql = null; _sourceSql = null;
_doNothing = false;
_updateIgnore.Clear();
_auditValueChangedDict.Clear(); _auditValueChangedDict.Clear();
_updateSetDict.Clear();
_batchValuesLimit = 0;
_batchAutoTransaction = false;
_params = null;
} }
public IInsertOrUpdate<T1> WithTransaction(DbTransaction transaction) public IInsertOrUpdate<T1> WithTransaction(DbTransaction transaction)
@ -204,6 +212,13 @@ namespace FreeSql.Internal.CommonProvider
return this; return this;
} }
public virtual IInsertOrUpdate<T1> BatchOptions(int valuesLimit, bool autoTransaction = true)
{
_batchValuesLimit = valuesLimit;
_batchAutoTransaction = autoTransaction;
return this;
}
protected string TableRuleInvoke() protected string TableRuleInvoke()
{ {
var tbname = _table?.DbName ?? ""; var tbname = _table?.DbName ?? "";
@ -353,19 +368,31 @@ namespace FreeSql.Internal.CommonProvider
if (threadTransaction != null) this.WithTransaction(threadTransaction); if (threadTransaction != null) this.WithTransaction(threadTransaction);
} }
if (_transaction != null || _orm.Ado.MasterPool == null) if (_transaction != null || _orm.Ado.MasterPool == null || _batchAutoTransaction == false)
{ {
_SplitSourceByIdentityValueIsNullFlag = 1; _SplitSourceByIdentityValueIsNullFlag = 1;
foreach (var tmpsource in ss.Item1) foreach (var tmpsource in ss.Item1)
{ {
_source = tmpsource; var pageTotal = Math.Ceiling(tmpsource.Count * 1.0 / _batchValuesLimit);
affrows += this.RawExecuteAffrows(); for (var pageNumber = 1; pageNumber <= pageTotal; pageNumber++)
{
_source = pageNumber > 1 ?
tmpsource.Skip((pageNumber - 1) * _batchValuesLimit).Take(_batchValuesLimit).ToList() :
tmpsource.Take(_batchValuesLimit).ToList();
affrows += this.RawExecuteAffrows();
}
} }
_SplitSourceByIdentityValueIsNullFlag = 2; _SplitSourceByIdentityValueIsNullFlag = 2;
foreach (var tmpsource in ss.Item2) foreach (var tmpsource in ss.Item2)
{ {
_source = tmpsource; var pageTotal = Math.Ceiling(tmpsource.Count * 1.0 / _batchValuesLimit);
affrows += this.RawExecuteAffrows(); for (var pageNumber = 1; pageNumber <= pageTotal; pageNumber++)
{
_source = pageNumber > 1 ?
tmpsource.Skip((pageNumber - 1) * _batchValuesLimit).Take(_batchValuesLimit).ToList() :
tmpsource.Take(_batchValuesLimit).ToList();
affrows += this.RawExecuteAffrows();
}
} }
} }
else else
@ -380,14 +407,26 @@ namespace FreeSql.Internal.CommonProvider
_SplitSourceByIdentityValueIsNullFlag = 1; _SplitSourceByIdentityValueIsNullFlag = 1;
foreach (var tmpsource in ss.Item1) foreach (var tmpsource in ss.Item1)
{ {
_source = tmpsource; var pageTotal = Math.Ceiling(tmpsource.Count * 1.0 / _batchValuesLimit);
affrows += this.RawExecuteAffrows(); for (var pageNumber = 1; pageNumber <= pageTotal; pageNumber++)
{
_source = pageNumber > 1 ?
tmpsource.Skip((pageNumber - 1) * _batchValuesLimit).Take(_batchValuesLimit).ToList() :
tmpsource.Take(_batchValuesLimit).ToList();
affrows += this.RawExecuteAffrows();
}
} }
_SplitSourceByIdentityValueIsNullFlag = 2; _SplitSourceByIdentityValueIsNullFlag = 2;
foreach (var tmpsource in ss.Item2) foreach (var tmpsource in ss.Item2)
{ {
_source = tmpsource; var pageTotal = Math.Ceiling(tmpsource.Count * 1.0 / _batchValuesLimit);
affrows += this.RawExecuteAffrows(); for (var pageNumber = 1; pageNumber <= pageTotal; pageNumber++)
{
_source = pageNumber > 1 ?
tmpsource.Skip((pageNumber - 1) * _batchValuesLimit).Take(_batchValuesLimit).ToList() :
tmpsource.Take(_batchValuesLimit).ToList();
affrows += this.RawExecuteAffrows();
}
} }
_transaction.Commit(); _transaction.Commit();
_orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, CoreStrings.Commit, null)); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, CoreStrings.Commit, null));
@ -461,7 +500,7 @@ namespace FreeSql.Internal.CommonProvider
} }
async public Task<int> ExecuteAffrowsAsync(CancellationToken cancellationToken = default) async public Task<int> ExecuteAffrowsAsync(CancellationToken cancellationToken = default)
{ {
if (_sourceSql != null) return this.RawExecuteAffrows(); if (_sourceSql != null) return await this.RawExecuteAffrowsAsync(cancellationToken);
var affrows = 0; var affrows = 0;
var ss = SplitSourceByIdentityValueIsNull(_source); var ss = SplitSourceByIdentityValueIsNull(_source);
try try
@ -472,19 +511,31 @@ namespace FreeSql.Internal.CommonProvider
if (threadTransaction != null) this.WithTransaction(threadTransaction); if (threadTransaction != null) this.WithTransaction(threadTransaction);
} }
if (_transaction != null || _orm.Ado.MasterPool == null) if (_transaction != null || _orm.Ado.MasterPool == null || _batchAutoTransaction == false)
{ {
_SplitSourceByIdentityValueIsNullFlag = 1; _SplitSourceByIdentityValueIsNullFlag = 1;
foreach (var tmpsource in ss.Item1) foreach (var tmpsource in ss.Item1)
{ {
_source = tmpsource; var pageTotal = Math.Ceiling(tmpsource.Count * 1.0 / _batchValuesLimit);
affrows += await this.RawExecuteAffrowsAsync(cancellationToken); for (var pageNumber = 1; pageNumber <= pageTotal; pageNumber++)
{
_source = pageNumber > 1 ?
tmpsource.Skip((pageNumber - 1) * _batchValuesLimit).Take(_batchValuesLimit).ToList() :
tmpsource.Take(_batchValuesLimit).ToList();
affrows += await this.RawExecuteAffrowsAsync(cancellationToken);
}
} }
_SplitSourceByIdentityValueIsNullFlag = 2; _SplitSourceByIdentityValueIsNullFlag = 2;
foreach (var tmpsource in ss.Item2) foreach (var tmpsource in ss.Item2)
{ {
_source = tmpsource; var pageTotal = Math.Ceiling(tmpsource.Count * 1.0 / _batchValuesLimit);
affrows += await this.RawExecuteAffrowsAsync(cancellationToken); for (var pageNumber = 1; pageNumber <= pageTotal; pageNumber++)
{
_source = pageNumber > 1 ?
tmpsource.Skip((pageNumber - 1) * _batchValuesLimit).Take(_batchValuesLimit).ToList() :
tmpsource.Take(_batchValuesLimit).ToList();
affrows += await this.RawExecuteAffrowsAsync(cancellationToken);
}
} }
} }
else else
@ -499,14 +550,26 @@ namespace FreeSql.Internal.CommonProvider
_SplitSourceByIdentityValueIsNullFlag = 1; _SplitSourceByIdentityValueIsNullFlag = 1;
foreach (var tmpsource in ss.Item1) foreach (var tmpsource in ss.Item1)
{ {
_source = tmpsource; var pageTotal = Math.Ceiling(tmpsource.Count * 1.0 / _batchValuesLimit);
affrows += await this.RawExecuteAffrowsAsync(cancellationToken); for (var pageNumber = 1; pageNumber <= pageTotal; pageNumber++)
{
_source = pageNumber > 1 ?
tmpsource.Skip((pageNumber - 1) * _batchValuesLimit).Take(_batchValuesLimit).ToList() :
tmpsource.Take(_batchValuesLimit).ToList();
affrows += await this.RawExecuteAffrowsAsync(cancellationToken);
}
} }
_SplitSourceByIdentityValueIsNullFlag = 2; _SplitSourceByIdentityValueIsNullFlag = 2;
foreach (var tmpsource in ss.Item2) foreach (var tmpsource in ss.Item2)
{ {
_source = tmpsource; var pageTotal = Math.Ceiling(tmpsource.Count * 1.0 / _batchValuesLimit);
affrows += await this.RawExecuteAffrowsAsync(cancellationToken); for (var pageNumber = 1; pageNumber <= pageTotal; pageNumber++)
{
_source = pageNumber > 1 ?
tmpsource.Skip((pageNumber - 1) * _batchValuesLimit).Take(_batchValuesLimit).ToList() :
tmpsource.Take(_batchValuesLimit).ToList();
affrows += await this.RawExecuteAffrowsAsync(cancellationToken);
}
} }
_transaction.Commit(); _transaction.Commit();
_orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, CoreStrings.Commit, null)); _orm.Aop.TraceAfterHandler?.Invoke(this, new Aop.TraceAfterEventArgs(transBefore, CoreStrings.Commit, null));