diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index 274e9e4a..29d66e23 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -13,8 +13,9 @@ namespace FreeSql { internal IFreeSql _orm; internal IFreeSql _fsql => _orm ?? throw new ArgumentNullException("请在 OnConfiguring 或 AddFreeDbContext 中配置 UseFreeSql"); - UnitOfWork _uowPriv; - internal UnitOfWork _uow => _uowPriv ?? (_uowPriv = new UnitOfWork(_fsql)); + IUnitOfWork _uowPriv; + internal IUnitOfWork _uow => _isUseUnitOfWork ? (_uowPriv ?? (_uowPriv = new UnitOfWork(_fsql))) : null; + internal bool _isUseUnitOfWork = true; //不使用工作单元事务 static ConcurrentDictionary _dicGetDbSetProps = new ConcurrentDictionary(); protected DbContext() { @@ -41,15 +42,14 @@ namespace FreeSql { } - Dictionary _dicSet = new Dictionary(); + protected Dictionary _dicSet = new Dictionary(); public DbSet Set() where TEntity : class => this.Set(typeof(TEntity)) as DbSet; - public object Set(Type entityType) { + public virtual object Set(Type entityType) { if (_dicSet.ContainsKey(entityType)) return _dicSet[entityType]; - var sd = Activator.CreateInstance(typeof(BaseDbSet<>).MakeGenericType(entityType), this); + var sd = Activator.CreateInstance(typeof(DbContextDbSet<>).MakeGenericType(entityType), this); _dicSet.Add(entityType, sd); return sd; } - protected Dictionary AllSets { get; } = new Dictionary(); internal class ExecCommandInfo { @@ -60,7 +60,7 @@ namespace FreeSql { } internal enum ExecCommandInfoType { Insert, Update, Delete } Queue _actions = new Queue(); - internal long _affrows = 0; + internal int _affrows = 0; internal void EnqueueAction(ExecCommandInfoType actionType, object dbSet, Type stateType, object state) { _actions.Enqueue(new ExecCommandInfo { actionType = actionType, dbSet = dbSet, stateType = stateType, state = state }); @@ -73,7 +73,11 @@ namespace FreeSql { public void Dispose() { if (_isdisposed) return; try { - _uow.Rollback(); + _actions.Clear(); + _dicSet.Clear(); + AllSets.Clear(); + + _uow?.Rollback(); } finally { _isdisposed = true; GC.SuppressFinalize(this); diff --git a/FreeSql.DbContext/DbContext/DbContextAsync.cs b/FreeSql.DbContext/DbContext/DbContextAsync.cs index 135de8db..bf2d2134 100644 --- a/FreeSql.DbContext/DbContext/DbContextAsync.cs +++ b/FreeSql.DbContext/DbContext/DbContextAsync.cs @@ -11,14 +11,17 @@ using System.Threading.Tasks; namespace FreeSql { partial class DbContext { - async public Task SaveChangesAsync() { + async public Task SaveChangesAsync() { await ExecCommandAsync(); - _uow.Commit(); - return _affrows; + _uow?.Commit(); + var ret = _affrows; + _affrows = 0; + return ret; } static Dictionary>>> _dicExecCommandDbContextBetchAsync = new Dictionary>>>(); async internal Task ExecCommandAsync() { + if (_actions.Any() == false) return; ExecCommandInfo oldinfo = null; var states = new List(); diff --git a/FreeSql.DbContext/DbContext/DbContextSync.cs b/FreeSql.DbContext/DbContext/DbContextSync.cs index e06a110e..ced1304a 100644 --- a/FreeSql.DbContext/DbContext/DbContextSync.cs +++ b/FreeSql.DbContext/DbContext/DbContextSync.cs @@ -10,14 +10,17 @@ using System.Linq.Expressions; namespace FreeSql { partial class DbContext { - public long SaveChanges() { + public int SaveChanges() { ExecCommand(); - _uow.Commit(); - return _affrows; + _uow?.Commit(); + var ret = _affrows; + _affrows = 0; + return ret; } static Dictionary>> _dicExecCommandDbContextBetch = new Dictionary>>(); internal void ExecCommand() { + if (_actions.Any() == false) return; ExecCommandInfo oldinfo = null; var states = new List(); diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index 1415f9b9..7b2028b8 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -7,29 +7,41 @@ using System.Linq.Expressions; namespace FreeSql { - internal class BaseDbSet : DbSet where TEntity : class { + internal class DbContextDbSet : DbSet where TEntity : class { - public BaseDbSet(DbContext ctx) { - if (ctx != null) { - _ctx = ctx; - _uow = ctx._uow; - _fsql = ctx._fsql; - } + public DbContextDbSet(DbContext ctx) { + _ctx = ctx; + _uow = ctx._uow; + _fsql = ctx._fsql; } } - public abstract partial class DbSet where TEntity : class { + public abstract partial class DbSet : IDisposable where TEntity : class { internal DbContext _ctx; - internal UnitOfWork _uow; + internal IUnitOfWork _uow; internal IFreeSql _fsql; - bool IsNoneDbContext => _ctx == null; protected virtual ISelect OrmSelect(object dywhere) { DbContextExecCommand(); //查询前先提交,否则会出脏读 return _fsql.Select(dywhere).WithTransaction(_uow?.GetOrBeginTransaction(false)).TrackToList(TrackToList); } + ~DbSet() { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() { + if (_isdisposed) return; + try { + this._dicUpdateTimes.Clear(); + this._states.Clear(); + } finally { + _isdisposed = true; + GC.SuppressFinalize(this); + } + } + protected virtual IInsert OrmInsert() => _fsql.Insert().WithTransaction(_uow?.GetOrBeginTransaction()); protected virtual IInsert OrmInsert(TEntity data) => _fsql.Insert(data).WithTransaction(_uow?.GetOrBeginTransaction()); protected virtual IInsert OrmInsert(IEnumerable data) => _fsql.Insert(data).WithTransaction(_uow?.GetOrBeginTransaction()); @@ -38,12 +50,10 @@ namespace FreeSql { protected virtual IDelete OrmDelete(object dywhere) => _fsql.Delete(dywhere).WithTransaction(_uow?.GetOrBeginTransaction()); internal void EnqueueToDbContext(DbContext.ExecCommandInfoType actionType, EntityState state) { - if (IsNoneDbContext == false) - _ctx.EnqueueAction(actionType, this, typeof(EntityState), state); + _ctx.EnqueueAction(actionType, this, typeof(EntityState), state); } - internal void IncrAffrows(long affrows) { - if (IsNoneDbContext == false) - _ctx._affrows += affrows; + internal void IncrAffrows(int affrows) { + _ctx._affrows += affrows; } internal void TrackToList(object list) { if (list == null) return; diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index ce271d4e..ab443e38 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -8,11 +8,8 @@ namespace FreeSql { partial class DbSet { Task DbContextExecCommandAsync() { - if (IsNoneDbContext == false) { - _dicUpdateTimes.Clear(); - return _ctx.ExecCommandAsync(); - } - return Task.CompletedTask; + _dicUpdateTimes.Clear(); + return _ctx.ExecCommandAsync(); } async Task DbContextBetchAddAsync(EntityState[] adds) { @@ -59,10 +56,7 @@ namespace FreeSql { return; } } else { - if (IsNoneDbContext) - IncrAffrows(await OrmInsert(data).ExecuteAffrowsAsync()); - else - EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(data)); + EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(data)); } } public Task AddAsync(TEntity data) => AddPrivAsync(data, true); @@ -94,12 +88,9 @@ namespace FreeSql { return; } } else { - if (IsNoneDbContext) - IncrAffrows(await OrmInsert(data).ExecuteAffrowsAsync()); - else - //进入队列,等待 SaveChanges 时执行 - foreach (var s in data) - EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(s)); + //进入队列,等待 SaveChanges 时执行 + foreach (var s in data) + EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(s)); } } #endregion @@ -154,56 +145,6 @@ namespace FreeSql { //等待下次对比再保存 return 0; } - - internal Task UpdateAffrowsAsync(TEntity data) => UpdateRangeAffrowsAsync(new[] { data }); - async internal Task UpdateRangeAffrowsAsync(IEnumerable data) { - if (CanUpdate(data, true) == false) return 0; - if (IsNoneDbContext) { - var dataarray = data.ToArray(); - var ups = new List(); - var totalAffrows = 0; - for (var a = 0; a < dataarray.Length + 1; a++) { - var item = a < dataarray.Length ? dataarray[a] : null; - if (item != null) { - var state = CreateEntityState(item); - state.Value = item; - ups.Add(state); - } - - var affrows = await DbContextBetchUpdatePrivAsync(ups.ToArray(), item == null); - if (affrows == -999) { //最后一个元素已被删除 - ups.RemoveAt(ups.Count - 1); - continue; - } - if (affrows == -998 || affrows == -997) { //没有执行更新 - var laststate = ups[ups.Count - 1]; - ups.Clear(); - if (affrows == -997) ups.Add(laststate); //保留最后一个 - } - if (affrows > 0) { - totalAffrows += affrows; - var islastNotUpdated = ups.Count != affrows; - var laststate = ups[ups.Count - 1]; - ups.Clear(); - if (islastNotUpdated) ups.Add(laststate); //保留最后一个 - } - } - IncrAffrows(totalAffrows); - return totalAffrows; - } - foreach (var item in data) { - if (_dicUpdateTimes.ContainsKey(item)) - await DbContextExecCommandAsync(); - _dicUpdateTimes.Add(item, 1); - - var state = CreateEntityState(item); - state.OldValue = item; - EnqueueToDbContext(DbContext.ExecCommandInfoType.Update, state); - } - return 0; - } - internal Task UpdateAsync(TEntity data) => UpdateAffrowsAsync(data); - internal Task UpdateRangeAsync(IEnumerable data) => UpdateRangeAffrowsAsync(data); #endregion #region RemoveAsync @@ -212,28 +153,6 @@ namespace FreeSql { var affrows = await this.OrmDelete(dels.Select(a => a.Value)).ExecuteAffrowsAsync(); return Math.Max(dels.Length, affrows); } - - internal Task RemoveAffrowsAsync(TEntity data) => RemoveRangeAffrowsAsync(new[] { data }); - async internal Task RemoveRangeAffrowsAsync(IEnumerable data) { - if (CanRemove(data, true) == false) return 0; - var dels = new List(); - foreach (var item in data) { - var state = CreateEntityState(item); - if (_states.ContainsKey(state.Key)) _states.Remove(state.Key); - _fsql.ClearEntityPrimaryValueWithIdentityAndGuid(item); - - if (IsNoneDbContext) dels.Add(state); - EnqueueToDbContext(DbContext.ExecCommandInfoType.Delete, state); - } - if (IsNoneDbContext) { - var affrows = await DbContextBetchRemoveAsync(dels.ToArray()); - IncrAffrows(affrows); - return affrows; - } - return 0; - } - internal Task RemoveAsync(TEntity data) => RemoveAffrowsAsync(data); - internal Task RemoveRangeAsync(IEnumerable data) => RemoveRangeAffrowsAsync(data); #endregion } } diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index f29df53e..63c6c881 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -7,10 +7,8 @@ namespace FreeSql { partial class DbSet { void DbContextExecCommand() { - if (IsNoneDbContext == false) { - _dicUpdateTimes.Clear(); - _ctx.ExecCommand(); - } + _dicUpdateTimes.Clear(); + _ctx.ExecCommand(); } int DbContextBetchAdd(EntityState[] adds) { @@ -56,12 +54,8 @@ namespace FreeSql { } return; } - } else { - if (IsNoneDbContext) - IncrAffrows(OrmInsert(data).ExecuteAffrows()); - else - EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(data)); - } + } else + EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(data)); } public void Add(TEntity data) => AddPriv(data, true); public void AddRange(IEnumerable data) { @@ -92,12 +86,9 @@ namespace FreeSql { return; } } else { - if (IsNoneDbContext) - IncrAffrows(OrmInsert(data).ExecuteAffrows()); - else - //进入队列,等待 SaveChanges 时执行 - foreach (var s in data) - EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(s)); + //进入队列,等待 SaveChanges 时执行 + foreach (var s in data) + EnqueueToDbContext(DbContext.ExecCommandInfoType.Insert, CreateEntityState(s)); } } #endregion @@ -154,42 +145,9 @@ namespace FreeSql { } Dictionary _dicUpdateTimes = new Dictionary(); - internal int UpdateAffrows(TEntity data) => UpdateRangeAffrows(new[] { data }); - internal int UpdateRangeAffrows(IEnumerable data) { - if (CanUpdate(data, true) == false) return 0; - if (IsNoneDbContext) { - var dataarray = data.ToArray(); - var ups = new List(); - var totalAffrows = 0; - for (var a = 0; a < dataarray.Length + 1; a++) { - var item = a < dataarray.Length ? dataarray[a] : null; - if (item != null) { - var state = CreateEntityState(item); - state.Value = item; - ups.Add(state); - } - - var affrows = DbContextBetchUpdatePriv(ups.ToArray(), item == null); - if (affrows == -999) { //最后一个元素已被删除 - ups.RemoveAt(ups.Count - 1); - continue; - } - if (affrows == -998 || affrows == -997) { //没有执行更新 - var laststate = ups[ups.Count - 1]; - ups.Clear(); - if (affrows == -997) ups.Add(laststate); //保留最后一个 - } - if (affrows > 0) { - totalAffrows += affrows; - var islastNotUpdated = ups.Count != affrows; - var laststate = ups[ups.Count - 1]; - ups.Clear(); - if (islastNotUpdated) ups.Add(laststate); //保留最后一个 - } - } - IncrAffrows(totalAffrows); - return totalAffrows; - } + public void Update(TEntity data) => UpdateRange(new[] { data }); + public void UpdateRange(IEnumerable data) { + if (CanUpdate(data, true) == false) return; foreach (var item in data) { if (_dicUpdateTimes.ContainsKey(item)) DbContextExecCommand(); @@ -199,10 +157,7 @@ namespace FreeSql { state.OldValue = item; EnqueueToDbContext(DbContext.ExecCommandInfoType.Update, state); } - return 0; } - public void Update(TEntity data) => UpdateAffrows(data); - public void UpdateRange(IEnumerable data) => UpdateRangeAffrows(data); #endregion #region Remove @@ -212,27 +167,17 @@ namespace FreeSql { return Math.Max(dels.Length, affrows); } - internal int RemoveAffrows(TEntity data) => RemoveRangeAffrows(new[] { data }); - internal int RemoveRangeAffrows(IEnumerable data) { - if (CanRemove(data, true) == false) return 0; - var dels = new List(); + public void Remove(TEntity data) => RemoveRange(new[] { data }); + public void RemoveRange(IEnumerable data) { + if (CanRemove(data, true) == false) return; foreach (var item in data) { var state = CreateEntityState(item); if (_states.ContainsKey(state.Key)) _states.Remove(state.Key); _fsql.ClearEntityPrimaryValueWithIdentityAndGuid(item); - if (IsNoneDbContext) dels.Add(state); EnqueueToDbContext(DbContext.ExecCommandInfoType.Delete, state); } - if (IsNoneDbContext) { - var affrows = DbContextBetchRemove(dels.ToArray()); - IncrAffrows(affrows); - return affrows; - } - return 0; } - public void Remove(TEntity data) => RemoveAffrows(data); - public void RemoveRange(IEnumerable data) => RemoveRangeAffrows(data); #endregion } } diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs new file mode 100644 index 00000000..b4460bfe --- /dev/null +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSql { + internal class RepositoryDbContext : DbContext where TEntity : class { + + protected BaseRepository _repos; + public RepositoryDbContext(IFreeSql orm, BaseRepository repos) : base() { + _orm = orm; + _repos = repos; + _isUseUnitOfWork = false; + } + + public override object Set(Type entityType) { + if (_dicSet.ContainsKey(entityType)) return _dicSet[entityType]; + var sd = Activator.CreateInstance(typeof(RepositoryDbSet<>).MakeGenericType(entityType), _repos); + _dicSet.Add(entityType, sd); + return sd; + } + + RepositoryDbSet _dbSet; + public RepositoryDbSet DbSet => _dbSet ?? (_dbSet = Set() as RepositoryDbSet); + } +} diff --git a/FreeSql.DbContext/Repository/Repository/RepositoryDbSet.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs similarity index 98% rename from FreeSql.DbContext/Repository/Repository/RepositoryDbSet.cs rename to FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs index 664e8e93..63a11ac8 100644 --- a/FreeSql.DbContext/Repository/Repository/RepositoryDbSet.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbSet.cs @@ -9,8 +9,9 @@ namespace FreeSql { protected BaseRepository _repos; public RepositoryDbSet(BaseRepository repos) { + _ctx = repos._db; _fsql = repos._fsql; - _uow = repos._uow; + _uow = repos.UnitOfWork; _repos = repos; } diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs new file mode 100644 index 00000000..4d7ce1e0 --- /dev/null +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryUnitOfWork.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Text; + +namespace FreeSql { + + public interface IRepositoryUnitOfWork : IUnitOfWork { + /// + /// 在工作单元内创建默认仓库类,工作单元下的仓储操作具有事务特点 + /// + /// + /// + /// 数据过滤 + 验证 + /// + DefaultRepository GetRepository(Expression> filter = null) where TEntity : class; + + /// + /// 在工作单元内创建仓库类,工作单元下的仓储操作具有事务特点 + /// + /// + /// 数据过滤 + 验证 + /// 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository + /// + GuidRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class; + } + + class RepositoryUnitOfWork : UnitOfWork, IRepositoryUnitOfWork { + + public RepositoryUnitOfWork(IFreeSql fsql) : base(fsql) { + } + + public GuidRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class { + var repos = new GuidRepository(_fsql, filter, asTable); + repos.UnitOfWork = this; + return repos; + } + + public DefaultRepository GetRepository(Expression> filter = null) where TEntity : class { + var repos = new DefaultRepository(_fsql, filter); + repos.UnitOfWork = this; + return repos; + } + } +} diff --git a/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs b/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs index ef1aeca3..4be01be5 100644 --- a/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs +++ b/FreeSql.DbContext/Repository/Extenssions/FreeSqlRepositoryExtenssions.cs @@ -22,7 +22,7 @@ public static class FreeSqlRepositoryExtenssions { } /// - /// 返回仓库类,适用 Insert 方法无须返回插入的数据 + /// 返回仓库类 /// /// /// diff --git a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs index 7ed0ebe0..f965aaf6 100644 --- a/FreeSql.DbContext/Repository/Repository/BaseRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/BaseRepository.cs @@ -11,9 +11,7 @@ namespace FreeSql { where TEntity : class { internal IFreeSql _fsql; - internal UnitOfWork _uow; - RepositoryDbSet _setPriv; - internal RepositoryDbSet _set => _setPriv ?? (_setPriv = new RepositoryDbSet(this)); + internal RepositoryDbContext _db; public IDataFilter DataFilter { get; } = new DataFilter(); Func _asTableVal; protected Func AsTable { @@ -32,45 +30,89 @@ namespace FreeSql { DataFilterUtil.SetRepositoryDataFilter(this, null); DataFilter.Apply("", filter); AsTable = asTable; + _db = new RepositoryDbContext(_fsql, this); } - public Type EntityType => _set._entityTypeInternal; - public IUpdate UpdateDiy => _set.OrmUpdateInternal(null); + ~BaseRepository() { + this.Dispose(); + } + bool _isdisposed = false; + public void Dispose() { + if (_isdisposed) return; + try { + _db.Dispose(); + this.DataFilter.Dispose(); + } finally { + _isdisposed = true; + GC.SuppressFinalize(this); + } + } + public IUnitOfWork UnitOfWork { get; set; } + public Type EntityType => _db.DbSet._entityTypeInternal; + public IUpdate UpdateDiy => _db.DbSet.OrmUpdateInternal(null); - public ISelect Select => _set.OrmSelectInternal(null); - public ISelect Where(Expression> exp) => _set.OrmSelectInternal(null).Where(exp); - public ISelect WhereIf(bool condition, Expression> exp) => _set.OrmSelectInternal(null).WhereIf(condition, exp); + public ISelect Select => _db.DbSet.OrmSelectInternal(null); + public ISelect Where(Expression> exp) => _db.DbSet.OrmSelectInternal(null).Where(exp); + public ISelect WhereIf(bool condition, Expression> exp) => _db.DbSet.OrmSelectInternal(null).WhereIf(condition, exp); - public int Delete(Expression> predicate) => _set.OrmDeleteInternal(null).Where(predicate).ExecuteAffrows(); - public Task DeleteAsync(Expression> predicate) => _set.OrmDeleteInternal(null).Where(predicate).ExecuteAffrowsAsync(); + public int Delete(Expression> predicate) => _db.DbSet.OrmDeleteInternal(null).Where(predicate).ExecuteAffrows(); + public Task DeleteAsync(Expression> predicate) => _db.DbSet.OrmDeleteInternal(null).Where(predicate).ExecuteAffrowsAsync(); - public int Delete(TEntity entity) => _set.RemoveAffrows(entity); - public Task DeleteAsync(TEntity entity) => _set.RemoveAffrowsAsync(entity); - public int Delete(IEnumerable entitys) => _set.RemoveRangeAffrows(entitys); - public Task DeleteAsync(IEnumerable entitys) => _set.RemoveRangeAffrowsAsync(entitys); + public int Delete(TEntity entity) { + _db.DbSet.Remove(entity); + return _db.SaveChanges(); + } + public Task DeleteAsync(TEntity entity) { + _db.DbSet.Remove(entity); + return _db.SaveChangesAsync(); + } + public int Delete(IEnumerable entitys) { + _db.DbSet.RemoveRange(entitys); + return _db.SaveChanges(); + } + public Task DeleteAsync(IEnumerable entitys) { + _db.DbSet.RemoveRange(entitys); + return _db.SaveChangesAsync(); + } public virtual TEntity Insert(TEntity entity) { - _set.Add(entity); + _db.DbSet.Add(entity); + _db.SaveChanges(); + return entity; + } + async public virtual Task InsertAsync(TEntity entity) { + await _db.DbSet.AddAsync(entity); + _db.SaveChanges(); return entity; } public virtual List Insert(IEnumerable entitys) { - _set.AddRange(entitys); + _db.DbSet.AddRange(entitys); + _db.SaveChanges(); return entitys.ToList(); } - async public virtual Task InsertAsync(TEntity entity) { - await _set.AddAsync(entity); - return entity; - } async public virtual Task> InsertAsync(IEnumerable entitys) { - await _set.AddRangeAsync(entitys); + await _db.DbSet.AddRangeAsync(entitys); + await _db.SaveChangesAsync(); return entitys.ToList(); } - public int Update(TEntity entity) => _set.UpdateAffrows(entity); - public Task UpdateAsync(TEntity entity) => _set.UpdateAffrowsAsync(entity); - public int Update(IEnumerable entitys) => _set.UpdateRangeAffrows(entitys); - public Task UpdateAsync(IEnumerable entitys) => _set.UpdateRangeAffrowsAsync(entitys); + public int Update(TEntity entity) { + _db.DbSet.Update(entity); + return _db.SaveChanges(); + } + public Task UpdateAsync(TEntity entity) { + _db.DbSet.Update(entity); + return _db.SaveChangesAsync(); + } + public int Update(IEnumerable entitys) { + _db.DbSet.UpdateRange(entitys); + return _db.SaveChanges(); + } + public Task UpdateAsync(IEnumerable entitys) { + _db.DbSet.UpdateRange(entitys); + return _db.SaveChangesAsync(); + } } public abstract class BaseRepository : BaseRepository, IRepository @@ -81,17 +123,19 @@ namespace FreeSql { public int Delete(TKey id) { var stateKey = string.Concat(id); - if (_set._statesInternal.ContainsKey(stateKey)) _set._statesInternal.Remove(stateKey); - return _set.OrmDeleteInternal(id).ExecuteAffrows(); + if (_db.DbSet._statesInternal.ContainsKey(stateKey)) + _db.DbSet._statesInternal.Remove(stateKey); + return _db.DbSet.OrmDeleteInternal(id).ExecuteAffrows(); } public Task DeleteAsync(TKey id) { var stateKey = string.Concat(id); - if (_set._statesInternal.ContainsKey(stateKey)) _set._statesInternal.Remove(stateKey); - return _set.OrmDeleteInternal(id).ExecuteAffrowsAsync(); + if (_db.DbSet._statesInternal.ContainsKey(stateKey)) + _db.DbSet._statesInternal.Remove(stateKey); + return _db.DbSet.OrmDeleteInternal(id).ExecuteAffrowsAsync(); } - public TEntity Find(TKey id) => _set.OrmSelectInternal(id).ToOne(); - public Task FindAsync(TKey id) => _set.OrmSelectInternal(id).ToOneAsync(); + public TEntity Find(TKey id) => _db.DbSet.OrmSelectInternal(id).ToOne(); + public Task FindAsync(TKey id) => _db.DbSet.OrmSelectInternal(id).ToOneAsync(); public TEntity Get(TKey id) => Find(id); public Task GetAsync(TKey id) => FindAsync(id); diff --git a/FreeSql.DbContext/Repository/Repository/IRepository.cs b/FreeSql.DbContext/Repository/Repository/IRepository.cs index d81c2080..631872a3 100644 --- a/FreeSql.DbContext/Repository/Repository/IRepository.cs +++ b/FreeSql.DbContext/Repository/Repository/IRepository.cs @@ -4,8 +4,9 @@ using System.Threading.Tasks; namespace FreeSql { - public interface IRepository { + public interface IRepository : IDisposable { Type EntityType { get; } + IUnitOfWork UnitOfWork { get; set; } } public interface IRepository : IReadOnlyRepository, IBasicRepository diff --git a/FreeSql.DbContext/Repository/Repository/RepositoryUnitOfWork.cs b/FreeSql.DbContext/Repository/Repository/RepositoryUnitOfWork.cs deleted file mode 100644 index 4526449d..00000000 --- a/FreeSql.DbContext/Repository/Repository/RepositoryUnitOfWork.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using System.Text; - -namespace FreeSql { - class RepositoryUnitOfWork : UnitOfWork, IRepositoryUnitOfWork { - - public RepositoryUnitOfWork(IFreeSql fsql) : base(fsql) { - } - - public GuidRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class { - var repos = new GuidRepository(_fsql, filter, asTable); - repos._uow = this; - return repos; - } - - public DefaultRepository GetRepository(Expression> filter = null) where TEntity : class { - var repos = new DefaultRepository(_fsql, filter); - repos._uow = this; - return repos; - } - } -} diff --git a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs index 48782be2..7a6d8c22 100644 --- a/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/IUnitOfWork.cs @@ -1,34 +1,16 @@ using System; using System.Collections.Generic; +using System.Data.Common; using System.Linq.Expressions; using System.Text; namespace FreeSql { public interface IUnitOfWork : IDisposable { + DbTransaction GetOrBeginTransaction(bool isCreate = true); + void Commit(); void Rollback(); } - - public interface IRepositoryUnitOfWork : IUnitOfWork { - - /// - /// 在工作单元内创建默认仓库类,工作单元下的仓储操作具有事务特点 - /// - /// - /// - /// 数据过滤 + 验证 - /// - DefaultRepository GetRepository(Expression> filter = null) where TEntity : class; - - /// - /// 在工作单元内创建仓库类,适用 Insert 方法无须返回插入的数据,工作单元下的仓储操作具有事务特点 - /// - /// - /// 数据过滤 + 验证 - /// 分表规则,参数:旧表名;返回:新表名 https://github.com/2881099/FreeSql/wiki/Repository - /// - GuidRepository GetGuidRepository(Expression> filter = null, Func asTable = null) where TEntity : class; - } } diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index 4957400f..8f9df3b2 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -21,7 +21,7 @@ namespace FreeSql { _tran = null; _conn = null; } - internal DbTransaction GetOrBeginTransaction(bool isCreate = true) { + public DbTransaction GetOrBeginTransaction(bool isCreate = true) { if (_tran != null) return _tran; if (isCreate == false) return null;