diff --git a/FreeSql.DbContext/DbContext/DbContext.cs b/FreeSql.DbContext/DbContext/DbContext.cs index 49f044f1..42188cb3 100644 --- a/FreeSql.DbContext/DbContext/DbContext.cs +++ b/FreeSql.DbContext/DbContext/DbContext.cs @@ -225,7 +225,7 @@ namespace FreeSql #endif #endregion - #region Queue Action + #region Queue PreCommand public class EntityChangeReport { public class ChangeInfo @@ -244,7 +244,7 @@ namespace FreeSql } internal List _entityChangeReport = new List(); public enum EntityChangeType { Insert, Update, Delete, SqlRaw } - internal class ExecCommandInfo + internal class PrevCommandInfo { public EntityChangeType changeType { get; set; } public IDbSet dbSet { get; set; } @@ -252,11 +252,11 @@ namespace FreeSql public Type entityType { get; set; } public object state { get; set; } } - Queue _actions = new Queue(); + Queue _prevCommands = new Queue(); internal int _affrows = 0; - internal void EnqueueAction(EntityChangeType changeType, IDbSet dbSet, Type stateType, Type entityType, object state) => - _actions.Enqueue(new ExecCommandInfo { changeType = changeType, dbSet = dbSet, stateType = stateType, entityType = entityType, state = state }); + internal void EnqueuePreCommand(EntityChangeType changeType, IDbSet dbSet, Type stateType, Type entityType, object state) => + _prevCommands.Enqueue(new PrevCommandInfo { changeType = changeType, dbSet = dbSet, stateType = stateType, entityType = entityType, state = state }); #endregion ~DbContext() => this.Dispose(); @@ -266,7 +266,7 @@ namespace FreeSql if (Interlocked.Increment(ref _disposeCounter) != 1) return; try { - _actions.Clear(); + _prevCommands.Clear(); foreach (var set in _listSet) try diff --git a/FreeSql.DbContext/DbContext/DbContextAsync.cs b/FreeSql.DbContext/DbContext/DbContextAsync.cs index 88969bd7..9195cd1b 100644 --- a/FreeSql.DbContext/DbContext/DbContextAsync.cs +++ b/FreeSql.DbContext/DbContext/DbContextAsync.cs @@ -1,8 +1,9 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Reflection; using System.Linq.Expressions; +using System.Reflection; using System.Threading.Tasks; #if net40 @@ -13,59 +14,58 @@ namespace FreeSql { async public virtual Task SaveChangesAsync() { - await ExecCommandAsync(); + await FlushCommandAsync(); return SaveChangesSuccess(); } - static Dictionary>>> _dicExecCommandDbContextBatchAsync = new Dictionary>>>(); - async internal Task ExecCommandAsync() + static ConcurrentDictionary>>> _dicFlushCommandDbSetBatchAsync = new ConcurrentDictionary>>>(); + async internal Task FlushCommandAsync() { - if (isExecCommanding) return; - if (_actions.Any() == false) return; - isExecCommanding = true; + if (isFlushCommanding) return; + if (_prevCommands.Any() == false) return; + isFlushCommanding = true; - ExecCommandInfo oldinfo = null; + PrevCommandInfo oldinfo = null; var states = new List(); - Func> dbContextBatch = methodName => + Task dbsetBatch(string method) { - if (_dicExecCommandDbContextBatchAsync.TryGetValue(oldinfo.stateType, out var trydic) == false) - trydic = new Dictionary>>(); - if (trydic.TryGetValue(methodName, out var tryfunc) == false) - { - var arrType = oldinfo.stateType.MakeArrayType(); - var dbsetType = oldinfo.dbSet.GetType().BaseType; - var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); + var tryfunc = _dicFlushCommandDbSetBatchAsync + .GetOrAdd(oldinfo.stateType, stateType => new ConcurrentDictionary>>()) + .GetOrAdd(method, methodName => + { + var arrType = oldinfo.stateType.MakeArrayType(); + var dbsetType = oldinfo.dbSet.GetType().BaseType; + var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); - var returnTarget = Expression.Label(typeof(Task)); - var parm1DbSet = Expression.Parameter(typeof(object)); - var parm2Vals = Expression.Parameter(typeof(object[])); - var var1Vals = Expression.Variable(arrType); - tryfunc = Expression.Lambda>>(Expression.Block( - new[] { var1Vals }, - Expression.Assign(var1Vals, Expression.Convert(global::FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), - Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), - Expression.Label(returnTarget, Expression.Default(typeof(Task))) - ), new[] { parm1DbSet, parm2Vals }).Compile(); - trydic.Add(methodName, tryfunc); - } + var returnTarget = Expression.Label(typeof(Task)); + var parm1DbSet = Expression.Parameter(typeof(object)); + var parm2Vals = Expression.Parameter(typeof(object[])); + var var1Vals = Expression.Variable(arrType); + return Expression.Lambda>>(Expression.Block( + new[] { var1Vals }, + Expression.Assign(var1Vals, Expression.Convert(global::FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), + Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), + Expression.Label(returnTarget, Expression.Default(typeof(Task))) + ), new[] { parm1DbSet, parm2Vals }).Compile(); + }); return tryfunc(oldinfo.dbSet, states.ToArray()); - }; - Func funcDelete = async () => + } + async Task funcDelete() { - _affrows += await dbContextBatch("DbContextBatchRemoveAsync"); + _affrows += await dbsetBatch("DbContextBatchRemoveAsync"); + states.Clear(); + } + async Task funcInsert() + { + _affrows += await dbsetBatch("DbContextBatchAddAsync"); states.Clear(); }; - Func funcInsert = async () => - { - _affrows += await dbContextBatch("DbContextBatchAddAsync"); - states.Clear(); - }; - Func funcUpdate = async (isLiveUpdate) => + async Task funcUpdate(bool isLiveUpdate) { var affrows = 0; - if (isLiveUpdate) affrows = await dbContextBatch("DbContextBatchUpdateNowAsync"); - else affrows = await dbContextBatch("DbContextBatchUpdateAsync"); + if (isLiveUpdate) affrows = await dbsetBatch("DbContextBatchUpdateNowAsync"); + else affrows = await dbsetBatch("DbContextBatchUpdateAsync"); if (affrows == -999) { //最后一个元素已被删除 states.RemoveAt(states.Count - 1); @@ -87,13 +87,13 @@ namespace FreeSql } }; - while (_actions.Any() || states.Any()) + while (_prevCommands.Any() || states.Any()) { - var info = _actions.Any() ? _actions.Dequeue() : null; + var info = _prevCommands.Any() ? _prevCommands.Dequeue() : null; if (oldinfo == null) oldinfo = info; var isLiveUpdate = false; - if (_actions.Any() == false && states.Any() || + if (_prevCommands.Any() == false && states.Any() || info != null && oldinfo.changeType != info.changeType || info != null && oldinfo.stateType != info.stateType || info != null && oldinfo.entityType != info.entityType) @@ -130,7 +130,7 @@ namespace FreeSql oldinfo = info; } } - isExecCommanding = false; + isFlushCommanding = false; } } } diff --git a/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs b/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs index b188b937..e1b0b1ef 100644 --- a/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs +++ b/FreeSql.DbContext/DbContext/DbContextScopedFreeSql.cs @@ -35,14 +35,14 @@ namespace FreeSql public ISelect Select() where T1 : class { - _resolveDbContext()?.ExecCommand(); + _resolveDbContext()?.FlushCommand(); return _originalFsql.Select().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction(false)); } public ISelect Select(object dywhere) where T1 : class => Select().WhereDynamic(dywhere); public IDelete Delete() where T1 : class { - _resolveDbContext()?.ExecCommand(); + _resolveDbContext()?.FlushCommand(); return _originalFsql.Delete().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); } public IDelete Delete(object dywhere) where T1 : class => Delete().WhereDynamic(dywhere); @@ -50,7 +50,7 @@ namespace FreeSql public IUpdate Update() where T1 : class { var db = _resolveDbContext(); - db?.ExecCommand(); + db?.FlushCommand(); var update = _originalFsql.Update().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); if (db?.Options.NoneParameter != null) update.NoneParameter(db.Options.NoneParameter.Value); return update; @@ -60,7 +60,7 @@ namespace FreeSql public IInsert Insert() where T1 : class { var db = _resolveDbContext(); - db?.ExecCommand(); + db?.FlushCommand(); var insert = _originalFsql.Insert().WithTransaction(_resolveUnitOfWork()?.GetOrBeginTransaction()); if (db?.Options.NoneParameter != null) insert.NoneParameter(db.Options.NoneParameter.Value); return insert; diff --git a/FreeSql.DbContext/DbContext/DbContextSync.cs b/FreeSql.DbContext/DbContext/DbContextSync.cs index 88fc4ca5..d6ad896d 100644 --- a/FreeSql.DbContext/DbContext/DbContextSync.cs +++ b/FreeSql.DbContext/DbContext/DbContextSync.cs @@ -1,8 +1,9 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Reflection; using System.Linq.Expressions; +using System.Reflection; namespace FreeSql { @@ -26,60 +27,62 @@ namespace FreeSql } public virtual int SaveChanges() { - ExecCommand(); + FlushCommand(); return SaveChangesSuccess(); } - static Dictionary>> _dicExecCommandDbContextBatch = new Dictionary>>(); - bool isExecCommanding = false; - internal void ExecCommand() + static ConcurrentDictionary>> _dicFlushCommandDbSetBatch = new ConcurrentDictionary>>(); + bool isFlushCommanding = false; + /// + /// 刷新队列中的命令 + /// + internal void FlushCommand() { - if (isExecCommanding) return; - if (_actions.Any() == false) return; - isExecCommanding = true; + if (isFlushCommanding) return; + if (_prevCommands.Any() == false) return; + isFlushCommanding = true; - ExecCommandInfo oldinfo = null; + PrevCommandInfo oldinfo = null; var states = new List(); - Func dbContextBatch = methodName => + int dbsetBatch(string method) { - if (_dicExecCommandDbContextBatch.TryGetValue(oldinfo.stateType, out var trydic) == false) - trydic = new Dictionary>(); - if (trydic.TryGetValue(methodName, out var tryfunc) == false) - { - var arrType = oldinfo.stateType.MakeArrayType(); - var dbsetType = oldinfo.dbSet.GetType().BaseType; - var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); + var tryfunc = _dicFlushCommandDbSetBatch + .GetOrAdd(oldinfo.stateType, stateType => new ConcurrentDictionary>()) + .GetOrAdd(method, methodName => + { + var arrType = oldinfo.stateType.MakeArrayType(); + var dbsetType = oldinfo.dbSet.GetType().BaseType; + var dbsetTypeMethod = dbsetType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { arrType }, null); - var returnTarget = Expression.Label(typeof(int)); - var parm1DbSet = Expression.Parameter(typeof(object)); - var parm2Vals = Expression.Parameter(typeof(object[])); - var var1Vals = Expression.Variable(arrType); - tryfunc = Expression.Lambda>(Expression.Block( - new[] { var1Vals }, - Expression.Assign(var1Vals, Expression.Convert(global::FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), - Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), - Expression.Label(returnTarget, Expression.Default(typeof(int))) - ), new[] { parm1DbSet, parm2Vals }).Compile(); - trydic.Add(methodName, tryfunc); - } + var returnTarget = Expression.Label(typeof(int)); + var parm1DbSet = Expression.Parameter(typeof(object)); + var parm2Vals = Expression.Parameter(typeof(object[])); + var var1Vals = Expression.Variable(arrType); + return Expression.Lambda>(Expression.Block( + new[] { var1Vals }, + Expression.Assign(var1Vals, Expression.Convert(global::FreeSql.Internal.Utils.GetDataReaderValueBlockExpression(arrType, parm2Vals), arrType)), + Expression.Return(returnTarget, Expression.Call(Expression.Convert(parm1DbSet, dbsetType), dbsetTypeMethod, var1Vals)), + Expression.Label(returnTarget, Expression.Default(typeof(int))) + ), new[] { parm1DbSet, parm2Vals }).Compile(); + }); return tryfunc(oldinfo.dbSet, states.ToArray()); - }; - Action funcDelete = () => + } + void funcDelete() { - _affrows += dbContextBatch("DbContextBatchRemove"); + _affrows += dbsetBatch("DbContextBatchRemove"); + states.Clear(); + } + void funcInsert() + { + _affrows += dbsetBatch("DbContextBatchAdd"); states.Clear(); }; - Action funcInsert = () => - { - _affrows += dbContextBatch("DbContextBatchAdd"); - states.Clear(); - }; - Action funcUpdate = isLiveUpdate => + void funcUpdate(bool isLiveUpdate) { var affrows = 0; - if (isLiveUpdate) affrows = dbContextBatch("DbContextBatchUpdateNow"); - else affrows = dbContextBatch("DbContextBatchUpdate"); + if (isLiveUpdate) affrows = dbsetBatch("DbContextBatchUpdateNow"); + else affrows = dbsetBatch("DbContextBatchUpdate"); if (affrows == -999) { //最后一个元素已被删除 states.RemoveAt(states.Count - 1); @@ -101,13 +104,13 @@ namespace FreeSql } }; - while (_actions.Any() || states.Any()) + while (_prevCommands.Any() || states.Any()) { - var info = _actions.Any() ? _actions.Dequeue() : null; + var info = _prevCommands.Any() ? _prevCommands.Dequeue() : null; if (oldinfo == null) oldinfo = info; var isLiveUpdate = false; - if (_actions.Any() == false && states.Any() || + if (_prevCommands.Any() == false && states.Any() || info != null && oldinfo.changeType != info.changeType || info != null && oldinfo.stateType != info.stateType || info != null && oldinfo.entityType != info.entityType) @@ -144,7 +147,7 @@ namespace FreeSql oldinfo = info; } } - isExecCommanding = false; + isFlushCommanding = false; } } } diff --git a/FreeSql.DbContext/DbSet/DbSet.cs b/FreeSql.DbContext/DbSet/DbSet.cs index 32efd9dd..1314a0d1 100644 --- a/FreeSql.DbContext/DbSet/DbSet.cs +++ b/FreeSql.DbContext/DbSet/DbSet.cs @@ -32,7 +32,7 @@ namespace FreeSql protected virtual ISelect OrmSelect(object dywhere) { - DbContextExecCommand(); //查询前先提交,否则会出脏读 + DbContextFlushCommand(); //查询前先提交,否则会出脏读 return _db.OrmOriginal.Select().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction(false)).TrackToList(TrackToList).WhereDynamic(dywhere); } @@ -70,7 +70,7 @@ namespace FreeSql protected virtual IDelete OrmDelete(object dywhere) => _db.OrmOriginal.Delete().AsType(_entityType).WithTransaction(_uow?.GetOrBeginTransaction()).WhereDynamic(dywhere); internal void EnqueueToDbContext(DbContext.EntityChangeType changeType, EntityState state) => - _db.EnqueueAction(changeType, this, typeof(EntityState), _entityType, state); + _db.EnqueuePreCommand(changeType, this, typeof(EntityState), _entityType, state); internal void IncrAffrows(int affrows) => _db._affrows += affrows; diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 1e756f53..774269ee 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -14,10 +14,10 @@ namespace FreeSql { partial class DbSet { - Task DbContextExecCommandAsync() + Task DbContextFlushCommandAsync() { _dicUpdateTimes.Clear(); - return _db.ExecCommandAsync(); + return _db.FlushCommandAsync(); } async Task DbContextBatchAddAsync(EntityState[] adds) @@ -43,7 +43,7 @@ namespace FreeSql case DataType.OdbcPostgreSQL: if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); IncrAffrows(1); _db.OrmOriginal.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); @@ -54,7 +54,7 @@ namespace FreeSql } else { - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); var newval = (await this.OrmInsert(data).ExecuteInsertedAsync()).First(); _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = newval, Type = DbContext.EntityChangeType.Insert }); IncrAffrows(1); @@ -67,7 +67,7 @@ namespace FreeSql default: if (_tableIdentitys.Length == 1 && _table.Primarys.Length == 1) { - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); var idtval = await this.OrmInsert(data).ExecuteIdentityAsync(); IncrAffrows(1); _db.OrmOriginal.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); @@ -102,7 +102,7 @@ namespace FreeSql case DataType.OdbcSqlServer: case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); var rets = await this.OrmInsert(data).ExecuteInsertedAsync(); if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.OrmOriginal.Ado.DataType} 的返回数据,与添加的数目不匹配"); _db._entityChangeReport.AddRange(rets.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a, Type = DbContext.EntityChangeType.Insert })); @@ -149,7 +149,7 @@ namespace FreeSql throw new ArgumentException($"{_table.Type.FullName} 类型的属性 {propertyName} 不是 OneToMany 或 ManyToMany 特性"); } - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); var oldEnable = _db.Options.EnableAddOrUpdateNavigateList; _db.Options.EnableAddOrUpdateNavigateList = false; try @@ -157,7 +157,7 @@ namespace FreeSql await AddOrUpdateNavigateListAsync(item, false, propertyName); if (tref.RefType == Internal.Model.TableRefType.OneToMany) { - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); //删除没有保存的数据,求出主体的条件 var deleteWhereParentParam = Expression.Parameter(typeof(object), "a"); Expression whereParentExp = null; @@ -401,7 +401,7 @@ namespace FreeSql foreach (var item in data) { if (_dicUpdateTimes.ContainsKey(item)) - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); _dicUpdateTimes.Add(item, 1); var state = CreateEntityState(item); @@ -429,7 +429,7 @@ namespace FreeSql /// async public Task RemoveAsync(Expression> predicate) { - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); return await this.OrmDelete(null).Where(predicate).ExecuteAffrowsAsync(); } #endregion @@ -449,10 +449,10 @@ namespace FreeSql if (flagExists == true && CanUpdate(data, false)) { - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); var affrows = _db._affrows; await UpdateRangePrivAsync(new[] { data }, false); - await DbContextExecCommandAsync(); + await DbContextFlushCommandAsync(); affrows = _db._affrows - affrows; if (affrows > 0) return; } diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index b49f5542..039fed10 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -13,10 +13,10 @@ namespace FreeSql partial class DbSet { - void DbContextExecCommand() + void DbContextFlushCommand() { _dicUpdateTimes.Clear(); - _db.ExecCommand(); + _db.FlushCommand(); } int DbContextBatchAdd(EntityState[] adds) @@ -42,7 +42,7 @@ namespace FreeSql case DataType.OdbcPostgreSQL: if (_tableIdentitys.Length == 1) { - DbContextExecCommand(); + DbContextFlushCommand(); var idtval = this.OrmInsert(data).ExecuteIdentity(); IncrAffrows(1); _db.OrmOriginal.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); @@ -53,7 +53,7 @@ namespace FreeSql } else { - DbContextExecCommand(); + DbContextFlushCommand(); var newval = this.OrmInsert(data).ExecuteInserted().First(); _db._entityChangeReport.Add(new DbContext.EntityChangeReport.ChangeInfo { Object = newval, Type = DbContext.EntityChangeType.Insert }); IncrAffrows(1); @@ -66,7 +66,7 @@ namespace FreeSql default: if (_tableIdentitys.Length == 1) { - DbContextExecCommand(); + DbContextFlushCommand(); var idtval = this.OrmInsert(data).ExecuteIdentity(); IncrAffrows(1); _db.OrmOriginal.SetEntityIdentityValueWithPrimary(_entityType, data, idtval); @@ -105,7 +105,7 @@ namespace FreeSql case DataType.OdbcSqlServer: case DataType.PostgreSQL: case DataType.OdbcPostgreSQL: - DbContextExecCommand(); + DbContextFlushCommand(); var rets = this.OrmInsert(data).ExecuteInserted(); if (rets.Count != data.Count()) throw new Exception($"特别错误:批量添加失败,{_db.OrmOriginal.Ado.DataType} 的返回数据,与添加的数目不匹配"); _db._entityChangeReport.AddRange(rets.Select(a => new DbContext.EntityChangeReport.ChangeInfo { Object = a, Type = DbContext.EntityChangeType.Insert })); @@ -161,7 +161,7 @@ namespace FreeSql throw new ArgumentException($"{_table.Type.FullName} 类型的属性 {propertyName} 不是 OneToMany 或 ManyToMany 特性"); } - DbContextExecCommand(); + DbContextFlushCommand(); var oldEnable = _db.Options.EnableAddOrUpdateNavigateList; _db.Options.EnableAddOrUpdateNavigateList = false; try @@ -169,7 +169,7 @@ namespace FreeSql AddOrUpdateNavigateList(item, false, propertyName); if (tref.RefType == Internal.Model.TableRefType.OneToMany) { - DbContextExecCommand(); + DbContextFlushCommand(); //删除没有保存的数据,求出主体的条件 var deleteWhereParentParam = Expression.Parameter(typeof(object), "a"); Expression whereParentExp = null; @@ -442,7 +442,7 @@ namespace FreeSql foreach (var item in data) { if (_dicUpdateTimes.ContainsKey(item)) - DbContextExecCommand(); + DbContextFlushCommand(); _dicUpdateTimes.Add(item, 1); var state = CreateEntityState(item); @@ -488,7 +488,7 @@ namespace FreeSql /// public int Remove(Expression> predicate) { - DbContextExecCommand(); + DbContextFlushCommand(); return this.OrmDelete(null).Where(predicate).ExecuteAffrows(); } #endregion @@ -512,10 +512,10 @@ namespace FreeSql if (flagExists == true && CanUpdate(data, false)) { - DbContextExecCommand(); + DbContextFlushCommand(); var affrows = _db._affrows; UpdateRangePriv(new[] { data }, false); - DbContextExecCommand(); + DbContextFlushCommand(); affrows = _db._affrows - affrows; if (affrows > 0) return; } diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index dbc7cdda..03dcd971 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -67,6 +67,11 @@ 实体变化事件 + + + 刷新队列中的命令 + + 是否开启一对多,多对多级联保存功能 @@ -115,6 +120,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 diff --git a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs index 7638d46d..458f4d65 100644 --- a/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs +++ b/FreeSql.DbContext/Repository/ContextSet/RepositoryDbContext.cs @@ -76,14 +76,14 @@ namespace FreeSql } public override int SaveChanges() { - ExecCommand(); + FlushCommand(); return SaveChangesSuccess(); } #if net40 #else async public override Task SaveChangesAsync() { - await ExecCommandAsync(); + await FlushCommandAsync(); return SaveChangesSuccess(); } #endif