mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 17:20:49 +08:00 
			
		
		
		
	## v0.3.27
- 增加 行级锁功能,适用修改实体; - 增加 FreeSql.Repository 默认依赖注入的方式,同时保留原有 Autofac; - 优化 FreeSql.Repository Insert 逻辑,参考了 FreeSql.DbContext; - 优化 FreeSql.IUpdate 参照 IInsert 对大批量更新,拆分执行; - 修复 FreeSql.IInsert ClearData 重复利用的 bug(使用 IgnoreColumns 进行大批量插入时会发生);
This commit is contained in:
		@@ -1,35 +1,63 @@
 | 
			
		||||
using FreeSql.Internal.Model;
 | 
			
		||||
using FreeSql.Extensions.EntityUtil;
 | 
			
		||||
using FreeSql.Internal.Model;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Data;
 | 
			
		||||
using System.Data.Common;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Linq.Expressions;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using FreeSql.Extensions;
 | 
			
		||||
 | 
			
		||||
namespace FreeSql {
 | 
			
		||||
 | 
			
		||||
	internal class BaseDbSet<TEntity> : DbSet<TEntity> where TEntity : class {
 | 
			
		||||
 | 
			
		||||
		public BaseDbSet(DbContext ctx) {
 | 
			
		||||
			_ctx = ctx;
 | 
			
		||||
			_fsql = ctx._fsql;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public abstract partial class DbSet<TEntity> where TEntity : class {
 | 
			
		||||
 | 
			
		||||
		internal DbContext _ctx;
 | 
			
		||||
		IFreeSql _fsql => _ctx._fsql;
 | 
			
		||||
		internal IFreeSql _fsql;
 | 
			
		||||
 | 
			
		||||
		ISelect<TEntity> OrmSelect(object dywhere) {
 | 
			
		||||
			_ctx.ExecCommand(); //查询前先提交,否则会出脏读
 | 
			
		||||
			return _fsql.Select<TEntity>(dywhere).WithTransaction(_ctx.GetOrBeginTransaction(false)).TrackToList(TrackToList);
 | 
			
		||||
		internal ISelect<TEntity> OrmSelect(object dywhere) {
 | 
			
		||||
			ExecuteCommand(); //查询前先提交,否则会出脏读
 | 
			
		||||
			return _fsql.Select<TEntity>(dywhere).WithTransaction(_ctx?.GetOrBeginTransaction(false)).TrackToList(TrackToList);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		IInsert<TEntity> OrmInsert() => _fsql.Insert<TEntity>().WithTransaction(_ctx.GetOrBeginTransaction());
 | 
			
		||||
		IInsert<TEntity> OrmInsert(TEntity data) => _fsql.Insert<TEntity>(data).WithTransaction(_ctx.GetOrBeginTransaction());
 | 
			
		||||
		IInsert<TEntity> OrmInsert(TEntity[] data) => _fsql.Insert<TEntity>(data).WithTransaction(_ctx.GetOrBeginTransaction());
 | 
			
		||||
		IInsert<TEntity> OrmInsert(IEnumerable<TEntity> data) => _fsql.Insert<TEntity>(data).WithTransaction(_ctx.GetOrBeginTransaction());
 | 
			
		||||
		internal virtual IInsert<TEntity> OrmInsert() => _fsql.Insert<TEntity>().WithTransaction(_ctx?.GetOrBeginTransaction());
 | 
			
		||||
		internal virtual IInsert<TEntity> OrmInsert(TEntity data) => _fsql.Insert<TEntity>(data).WithTransaction(_ctx?.GetOrBeginTransaction());
 | 
			
		||||
		internal virtual IInsert<TEntity> OrmInsert(TEntity[] data) => _fsql.Insert<TEntity>(data).WithTransaction(_ctx?.GetOrBeginTransaction());
 | 
			
		||||
		internal virtual IInsert<TEntity> OrmInsert(IEnumerable<TEntity> data) => _fsql.Insert<TEntity>(data).WithTransaction(_ctx?.GetOrBeginTransaction());
 | 
			
		||||
 | 
			
		||||
		IUpdate<TEntity> OrmUpdate(object dywhere) => _fsql.Update<TEntity>(dywhere).WithTransaction(_ctx.GetOrBeginTransaction());
 | 
			
		||||
		IDelete<TEntity> OrmDelete(object dywhere) => _fsql.Delete<TEntity>(dywhere).WithTransaction(_ctx.GetOrBeginTransaction());
 | 
			
		||||
		internal virtual IUpdate<TEntity> OrmUpdate(object dywhere) => _fsql.Update<TEntity>(dywhere).WithTransaction(_ctx?.GetOrBeginTransaction());
 | 
			
		||||
		internal virtual IDelete<TEntity> OrmDelete(object dywhere) => _fsql.Delete<TEntity>(dywhere).WithTransaction(_ctx?.GetOrBeginTransaction());
 | 
			
		||||
 | 
			
		||||
		internal void EnqueueAction(DbContext.ExecCommandInfoType actionType, object dbSet, Type stateType, object state) {
 | 
			
		||||
			_ctx?.EnqueueAction(actionType, dbSet, stateType, state);
 | 
			
		||||
		}
 | 
			
		||||
		internal void ExecuteCommand() {
 | 
			
		||||
			_ctx?.ExecCommand();
 | 
			
		||||
		}
 | 
			
		||||
		internal void IncrAffrows(long affrows) {
 | 
			
		||||
			if (_ctx != null)
 | 
			
		||||
				_ctx._affrows += affrows;
 | 
			
		||||
		}
 | 
			
		||||
		internal void TrackToList(object list) {
 | 
			
		||||
			if (list == null) return;
 | 
			
		||||
			var ls = list as IList<TEntity>;
 | 
			
		||||
			if (ls == null) return;
 | 
			
		||||
 | 
			
		||||
			foreach (var item in ls) {
 | 
			
		||||
				var key = _fsql.GetEntityKeyString(item);
 | 
			
		||||
				if (_states.ContainsKey(key)) {
 | 
			
		||||
					_fsql.MapEntityValue(item, _states[key].Value);
 | 
			
		||||
					_states[key].Time = DateTime.Now;
 | 
			
		||||
				} else {
 | 
			
		||||
					_states.Add(key, CreateEntityState(item));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ISelect<TEntity> Select => this.OrmSelect(null);
 | 
			
		||||
		public ISelect<TEntity> Where(Expression<Func<TEntity, bool>> exp) => this.OrmSelect(null).Where(exp);
 | 
			
		||||
@@ -42,24 +70,6 @@ namespace FreeSql {
 | 
			
		||||
		ColumnInfo[] _tableIdentitys => _tableIdentitysPriv ?? (_tableIdentitysPriv = _table.Primarys.Where(a => a.Attribute.IsIdentity).ToArray()); 
 | 
			
		||||
		Type _entityType = typeof(TEntity);
 | 
			
		||||
 | 
			
		||||
		bool _versionColumnPrivPrivIsInit = false;
 | 
			
		||||
		ColumnInfo _versionColumnPriv;
 | 
			
		||||
		ColumnInfo _versionColumn {
 | 
			
		||||
			get {
 | 
			
		||||
				if (_versionColumnPrivPrivIsInit == false) {
 | 
			
		||||
					var vc = _table.Properties.Where(a => _table.ColumnsByCs.ContainsKey(a.Key) && a.Value.GetCustomAttributes(typeof(VersionAttribute), false).Any());
 | 
			
		||||
					if (vc.Any()) {
 | 
			
		||||
						var col = _table.ColumnsByCs[vc.Last().Key];
 | 
			
		||||
						if (col.CsType.IsNullableType() || col.CsType.IsNumberType() == false)
 | 
			
		||||
							throw new Exception($"属性{col.CsName} 被标注为行级锁(Version),但其必须为数字类型,并且不可为 Nullable");
 | 
			
		||||
						_versionColumnPriv = col;
 | 
			
		||||
					}
 | 
			
		||||
					_versionColumnPrivPrivIsInit = true;
 | 
			
		||||
				}
 | 
			
		||||
				return _versionColumnPriv;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public class EntityState {
 | 
			
		||||
			public EntityState(TEntity value, string key) {
 | 
			
		||||
				this.Value = value;
 | 
			
		||||
@@ -202,35 +212,12 @@ namespace FreeSql {
 | 
			
		||||
				if (isThrow) throw new Exception($"不可删除,未设置主键的值:{_fsql.GetEntityString(data)}");
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
			if (_states.TryGetValue(key, out var tryval) == false) {
 | 
			
		||||
				if (isThrow) throw new Exception($"不可更新,数据未被跟踪,应该先查询:{_fsql.GetEntityString(data)}");
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
			//if (_states.TryGetValue(key, out var tryval) == false) {
 | 
			
		||||
			//	if (isThrow) throw new Exception($"不可删除,数据未被跟踪,应该先查询:{_fsql.GetEntityString(data)}");
 | 
			
		||||
			//	return false;
 | 
			
		||||
			//}
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		#endregion
 | 
			
		||||
		
 | 
			
		||||
		void TrackToList(object list) {
 | 
			
		||||
			if (list == null) return;
 | 
			
		||||
			var ls = list as IList<TEntity>;
 | 
			
		||||
			if (ls == null) return;
 | 
			
		||||
 | 
			
		||||
			foreach (var item in ls) {
 | 
			
		||||
				var key = _fsql.GetEntityKeyString(item);
 | 
			
		||||
				if (_states.ContainsKey(key)) {
 | 
			
		||||
					_fsql.MapEntityValue(item, _states[key].Value);
 | 
			
		||||
					_states[key].Time = DateTime.Now;
 | 
			
		||||
				} else {
 | 
			
		||||
					_states.Add(key, CreateEntityState(item));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	internal class BaseDbSet<TEntity> : DbSet<TEntity> where TEntity : class {
 | 
			
		||||
		
 | 
			
		||||
		public BaseDbSet(DbContext ctx) {
 | 
			
		||||
			_ctx = ctx;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user