mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 17:20:49 +08:00 
			
		
		
		
	- 增加 IUpdate.SetSource ignoreVersion 参数可实现忽略乐观锁;#1161
This commit is contained in:
		@@ -2878,13 +2878,14 @@
 | 
				
			|||||||
            <param name="source">实体</param>
 | 
					            <param name="source">实体</param>
 | 
				
			||||||
            <returns></returns>
 | 
					            <returns></returns>
 | 
				
			||||||
        </member>
 | 
					        </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>
 | 
					            <summary>
 | 
				
			||||||
            更新数据,设置更新的实体集合<para></para>
 | 
					            更新数据,设置更新的实体集合<para></para>
 | 
				
			||||||
            注意:实体必须定义主键,并且最终会自动附加条件 where id in (source.Id)
 | 
					            注意:实体必须定义主键,并且最终会自动附加条件 where id in (source.Id)
 | 
				
			||||||
            </summary>
 | 
					            </summary>
 | 
				
			||||||
            <param name="source">实体集合</param>
 | 
					            <param name="source">实体集合</param>
 | 
				
			||||||
            <param name="tempPrimarys">根据临时主键更新,a => a.Name | a => new{a.Name,a.Time} | a => new[]{"name","time"}</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>
 | 
					            <returns></returns>
 | 
				
			||||||
        </member>
 | 
					        </member>
 | 
				
			||||||
        <member name="M:FreeSql.IUpdate`1.SetSourceIgnore(`0,System.Func{System.Object,System.Boolean})">
 | 
					        <member name="M:FreeSql.IUpdate`1.SetSourceIgnore(`0,System.Func{System.Object,System.Boolean})">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -73,8 +73,9 @@ namespace FreeSql
 | 
				
			|||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="source">实体集合</param>
 | 
					        /// <param name="source">实体集合</param>
 | 
				
			||||||
        /// <param name="tempPrimarys">根据临时主键更新,a => a.Name | a => new{a.Name,a.Time} | a => new[]{"name","time"}</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>
 | 
					        /// <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>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 更新数据,设置更新的实体,同时设置忽略的列<para></para>
 | 
					        /// 更新数据,设置更新的实体,同时设置忽略的列<para></para>
 | 
				
			||||||
        /// 忽略 null 属性:fsql.Update<T>().SetSourceAndIgnore(item, colval => colval == null)<para></para>
 | 
					        /// 忽略 null 属性:fsql.Update<T>().SetSourceAndIgnore(item, colval => colval == null)<para></para>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,6 +21,8 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
        public Dictionary<string, bool> _auditValueChangedDict = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase);
 | 
					        public Dictionary<string, bool> _auditValueChangedDict = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase);
 | 
				
			||||||
        public TableInfo _table;
 | 
					        public TableInfo _table;
 | 
				
			||||||
        public ColumnInfo[] _tempPrimarys;
 | 
					        public ColumnInfo[] _tempPrimarys;
 | 
				
			||||||
 | 
					        public ColumnInfo _versionColumn;
 | 
				
			||||||
 | 
					        public bool _ignoreVersion = false;
 | 
				
			||||||
        public Func<string, string> _tableRule;
 | 
					        public Func<string, string> _tableRule;
 | 
				
			||||||
        public StringBuilder _where = new StringBuilder();
 | 
					        public StringBuilder _where = new StringBuilder();
 | 
				
			||||||
        public List<GlobalFilter.Item> _whereGlobalFilter;
 | 
					        public List<GlobalFilter.Item> _whereGlobalFilter;
 | 
				
			||||||
@@ -51,6 +53,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
            _commonExpression = commonExpression;
 | 
					            _commonExpression = commonExpression;
 | 
				
			||||||
            _table = _commonUtils.GetTableByEntity(typeof(T1));
 | 
					            _table = _commonUtils.GetTableByEntity(typeof(T1));
 | 
				
			||||||
            _tempPrimarys = _table?.Primarys ?? new ColumnInfo[0];
 | 
					            _tempPrimarys = _table?.Primarys ?? new ColumnInfo[0];
 | 
				
			||||||
 | 
					            _versionColumn = _table?.VersionColumn;
 | 
				
			||||||
            _noneParameter = _orm.CodeFirst.IsNoneCommandParameter;
 | 
					            _noneParameter = _orm.CodeFirst.IsNoneCommandParameter;
 | 
				
			||||||
            this.Where(_commonUtils.WhereObject(_table, "", dywhere));
 | 
					            this.Where(_commonUtils.WhereObject(_table, "", dywhere));
 | 
				
			||||||
            if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure<T1>();
 | 
					            if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure<T1>();
 | 
				
			||||||
@@ -86,7 +89,8 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
            _whereGlobalFilter = _orm.GlobalFilter.GetFilters();
 | 
					            _whereGlobalFilter = _orm.GlobalFilter.GetFilters();
 | 
				
			||||||
            _batchProgress = null;
 | 
					            _batchProgress = null;
 | 
				
			||||||
            _interceptSql = null;
 | 
					            _interceptSql = null;
 | 
				
			||||||
            _updateVersionValue = null;
 | 
					            _versionColumn = _table?.VersionColumn;
 | 
				
			||||||
 | 
					            _ignoreVersion = false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public IUpdate<T1> WithTransaction(DbTransaction transaction)
 | 
					        public IUpdate<T1> WithTransaction(DbTransaction transaction)
 | 
				
			||||||
@@ -129,16 +133,16 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        protected void ValidateVersionAndThrow(int affrows, string sql, DbParameter[] dbParms)
 | 
					        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)
 | 
					                if (affrows != _source.Count)
 | 
				
			||||||
                    throw new DbUpdateVersionException(CoreStrings.DbUpdateVersionException_RowLevelOptimisticLock(_source.Count, affrows), _table, sql, dbParms, affrows, _source.Select(a => (object)a));
 | 
					                    throw new DbUpdateVersionException(CoreStrings.DbUpdateVersionException_RowLevelOptimisticLock(_source.Count, affrows), _table, sql, dbParms, affrows, _source.Select(a => (object)a));
 | 
				
			||||||
                foreach (var d in _source)
 | 
					                foreach (var d in _source)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (_table.VersionColumn.Attribute.MapType == typeof(byte[]))
 | 
					                    if (_versionColumn.Attribute.MapType == typeof(byte[]))
 | 
				
			||||||
                        _orm.SetEntityValueWithPropertyName(_table.Type, d, _table.VersionColumn.CsName, _updateVersionValue);
 | 
					                        _orm.SetEntityValueWithPropertyName(_table.Type, d, _versionColumn.CsName, _updateVersionValue);
 | 
				
			||||||
                    else
 | 
					                    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(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;
 | 
					            if (source == null || source.Any() == false) return this;
 | 
				
			||||||
            GetDictionaryTableInfo(source.FirstOrDefault(), _orm, ref _table);
 | 
					            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);
 | 
					                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();
 | 
					                _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;
 | 
					            return this;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        public IUpdate<T1> SetSourceIgnore(T1 source, Func<object, bool> ignore)
 | 
					        public IUpdate<T1> SetSourceIgnore(T1 source, Func<object, bool> ignore)
 | 
				
			||||||
@@ -768,6 +774,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
            var newtb = _commonUtils.GetTableByEntity(entityType);
 | 
					            var newtb = _commonUtils.GetTableByEntity(entityType);
 | 
				
			||||||
            _table = newtb ?? throw new Exception(CoreStrings.Type_AsType_Parameter_Error("IUpdate"));
 | 
					            _table = newtb ?? throw new Exception(CoreStrings.Type_AsType_Parameter_Error("IUpdate"));
 | 
				
			||||||
            _tempPrimarys = _table.Primarys;
 | 
					            _tempPrimarys = _table.Primarys;
 | 
				
			||||||
 | 
					            _versionColumn = _ignoreVersion ? null : _table.VersionColumn;
 | 
				
			||||||
            if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType);
 | 
					            if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType);
 | 
				
			||||||
            IgnoreCanUpdate();
 | 
					            IgnoreCanUpdate();
 | 
				
			||||||
            return this;
 | 
					            return this;
 | 
				
			||||||
@@ -988,13 +995,13 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
                        sb.Append(", ").Append(_commonUtils.QuoteSqlName(col.Attribute.Name)).Append(" = ").Append(col.DbUpdateValue);
 | 
					                        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);
 | 
					                var vcname = _commonUtils.QuoteSqlName(_versionColumn.Attribute.Name);
 | 
				
			||||||
                if (_table.VersionColumn.Attribute.MapType == typeof(byte[]))
 | 
					                if (_versionColumn.Attribute.MapType == typeof(byte[]))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    _updateVersionValue = Utils.GuidToBytes(Guid.NewGuid());
 | 
					                    _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
 | 
					                else
 | 
				
			||||||
                    sb.Append(", ").Append(vcname).Append(" = ").Append(_commonUtils.IsNull(vcname, 0)).Append(" + 1");
 | 
					                    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);
 | 
					                    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)
 | 
					                if (string.IsNullOrEmpty(versionCondi) == false)
 | 
				
			||||||
                    sb.Append(" AND ").Append(versionCondi);
 | 
					                    sb.Append(" AND ").Append(versionCondi);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user