- 增加 IUpdate.SetSource ignoreVersion 参数可实现忽略乐观锁;#1161

This commit is contained in:
2881099 2022-06-23 13:27:06 +08:00
parent 1155ffc781
commit 672895537f
3 changed files with 23 additions and 14 deletions

View File

@ -2878,13 +2878,14 @@
<param name="source">实体</param>
<returns></returns>
</member>
<member name="M:FreeSql.IUpdate`1.SetSource(System.Collections.Generic.IEnumerable{`0},System.Linq.Expressions.Expression{System.Func{`0,System.Object}})">
<member name="M:FreeSql.IUpdate`1.SetSource(System.Collections.Generic.IEnumerable{`0},System.Linq.Expressions.Expression{System.Func{`0,System.Object}},System.Boolean)">
<summary>
更新数据,设置更新的实体集合<para></para>
注意:实体必须定义主键,并且最终会自动附加条件 where id in (source.Id)
</summary>
<param name="source">实体集合</param>
<param name="tempPrimarys">根据临时主键更新a => a.Name | a => new{a.Name,a.Time} | a => new[]{"name","time"}</param>
<param name="validateVersion">是否检查 IsVersion 乐观锁版本号</param>
<returns></returns>
</member>
<member name="M:FreeSql.IUpdate`1.SetSourceIgnore(`0,System.Func{System.Object,System.Boolean})">

View File

@ -73,8 +73,9 @@ namespace FreeSql
/// </summary>
/// <param name="source">实体集合</param>
/// <param name="tempPrimarys">根据临时主键更新a => a.Name | a => new{a.Name,a.Time} | a => new[]{"name","time"}</param>
/// <param name="ignoreVersion">忽略 IsVersion 乐观锁版本号</param>
/// <returns></returns>
IUpdate<T1> SetSource(IEnumerable<T1> source, Expression<Func<T1, object>> tempPrimarys = null);
IUpdate<T1> SetSource(IEnumerable<T1> source, Expression<Func<T1, object>> tempPrimarys = null, bool ignoreVersion = false);
/// <summary>
/// 更新数据,设置更新的实体,同时设置忽略的列<para></para>
/// 忽略 null 属性fsql.Update&lt;T&gt;().SetSourceAndIgnore(item, colval => colval == null)<para></para>

View File

@ -21,6 +21,8 @@ namespace FreeSql.Internal.CommonProvider
public Dictionary<string, bool> _auditValueChangedDict = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase);
public TableInfo _table;
public ColumnInfo[] _tempPrimarys;
public ColumnInfo _versionColumn;
public bool _ignoreVersion = false;
public Func<string, string> _tableRule;
public StringBuilder _where = new StringBuilder();
public List<GlobalFilter.Item> _whereGlobalFilter;
@ -51,6 +53,7 @@ namespace FreeSql.Internal.CommonProvider
_commonExpression = commonExpression;
_table = _commonUtils.GetTableByEntity(typeof(T1));
_tempPrimarys = _table?.Primarys ?? new ColumnInfo[0];
_versionColumn = _table?.VersionColumn;
_noneParameter = _orm.CodeFirst.IsNoneCommandParameter;
this.Where(_commonUtils.WhereObject(_table, "", dywhere));
if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure<T1>();
@ -86,7 +89,8 @@ namespace FreeSql.Internal.CommonProvider
_whereGlobalFilter = _orm.GlobalFilter.GetFilters();
_batchProgress = null;
_interceptSql = null;
_updateVersionValue = null;
_versionColumn = _table?.VersionColumn;
_ignoreVersion = false;
}
public IUpdate<T1> WithTransaction(DbTransaction transaction)
@ -129,16 +133,16 @@ namespace FreeSql.Internal.CommonProvider
protected void ValidateVersionAndThrow(int affrows, string sql, DbParameter[] dbParms)
{
if (_table.VersionColumn != null && _source.Count > 0)
if (_versionColumn != null && _source.Count > 0)
{
if (affrows != _source.Count)
throw new DbUpdateVersionException(CoreStrings.DbUpdateVersionException_RowLevelOptimisticLock(_source.Count, affrows), _table, sql, dbParms, affrows, _source.Select(a => (object)a));
foreach (var d in _source)
{
if (_table.VersionColumn.Attribute.MapType == typeof(byte[]))
_orm.SetEntityValueWithPropertyName(_table.Type, d, _table.VersionColumn.CsName, _updateVersionValue);
if (_versionColumn.Attribute.MapType == typeof(byte[]))
_orm.SetEntityValueWithPropertyName(_table.Type, d, _versionColumn.CsName, _updateVersionValue);
else
_orm.SetEntityIncrByWithPropertyName(_table.Type, d, _table.VersionColumn.CsName, 1);
_orm.SetEntityIncrByWithPropertyName(_table.Type, d, _versionColumn.CsName, 1);
}
}
}
@ -484,7 +488,7 @@ namespace FreeSql.Internal.CommonProvider
}
public IUpdate<T1> SetSource(T1 source) => this.SetSource(new[] { source });
public IUpdate<T1> SetSource(IEnumerable<T1> source, Expression<Func<T1, object>> tempPrimarys = null)
public IUpdate<T1> SetSource(IEnumerable<T1> source, Expression<Func<T1, object>> tempPrimarys = null, bool ignoreVersion = false)
{
if (source == null || source.Any() == false) return this;
GetDictionaryTableInfo(source.FirstOrDefault(), _orm, ref _table);
@ -496,6 +500,8 @@ namespace FreeSql.Internal.CommonProvider
var cols = _commonExpression.ExpressionSelectColumns_MemberAccess_New_NewArrayInit(null, null, tempPrimarys?.Body, false, null).Distinct().ToDictionary(a => a);
_tempPrimarys = cols.Keys.Select(a => _table.Columns.TryGetValue(a, out var col) ? col : null).ToArray().Where(a => a != null).ToArray();
}
_ignoreVersion = ignoreVersion;
_versionColumn = _ignoreVersion ? null : _table?.VersionColumn;
return this;
}
public IUpdate<T1> SetSourceIgnore(T1 source, Func<object, bool> ignore)
@ -768,6 +774,7 @@ namespace FreeSql.Internal.CommonProvider
var newtb = _commonUtils.GetTableByEntity(entityType);
_table = newtb ?? throw new Exception(CoreStrings.Type_AsType_Parameter_Error("IUpdate"));
_tempPrimarys = _table.Primarys;
_versionColumn = _ignoreVersion ? null : _table.VersionColumn;
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType);
IgnoreCanUpdate();
return this;
@ -988,13 +995,13 @@ namespace FreeSql.Internal.CommonProvider
sb.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(col.DbUpdateValue);
}
if (_table.VersionColumn != null)
if (_versionColumn != null)
{
var vcname = _commonUtils.QuoteSqlName(_table.VersionColumn.Attribute.Name);
if (_table.VersionColumn.Attribute.MapType == typeof(byte[]))
var vcname = _commonUtils.QuoteSqlName(_versionColumn.Attribute.Name);
if (_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));
sb.Append(", ").Append(vcname).Append(" = ").Append(_commonUtils.GetNoneParamaterSqlValue(_paramsSource, "uv", _versionColumn, _versionColumn.Attribute.MapType, _updateVersionValue));
}
else
sb.Append(", ").Append(vcname).Append(" = ").Append(_commonUtils.IsNull(vcname, 0)).Append(" + 1");
@ -1023,9 +1030,9 @@ namespace FreeSql.Internal.CommonProvider
sb.Append(" AND ").Append(globalFilterCondi);
}
if (_table.VersionColumn != null)
if (_versionColumn != null)
{
var versionCondi = WhereCaseSource(_table.VersionColumn.CsName, sqlval => sqlval);
var versionCondi = WhereCaseSource(_versionColumn.CsName, sqlval => sqlval);
if (string.IsNullOrEmpty(versionCondi) == false)
sb.Append(" AND ").Append(versionCondi);
}