diff --git a/FreeSql.DbContext/DbSet/DbSetAsync.cs b/FreeSql.DbContext/DbSet/DbSetAsync.cs index 07123ef8..3d7df0bc 100644 --- a/FreeSql.DbContext/DbSet/DbSetAsync.cs +++ b/FreeSql.DbContext/DbSet/DbSetAsync.cs @@ -160,8 +160,7 @@ namespace FreeSql await DbContextExecCommandAsync(); //删除没有保存的数据 var propValEach = GetItemValue(item, prop) as IEnumerable; - await _db.Orm.Select().AsType(tref.RefEntityType).WhereDynamic(propValEach, true) - .ToDelete().ExecuteAffrowsAsync(); + await _db.Orm.Delete().AsType(tref.RefEntityType).WhereDynamic(propValEach, true).ExecuteAffrowsAsync(); } } finally diff --git a/FreeSql.DbContext/DbSet/DbSetSync.cs b/FreeSql.DbContext/DbSet/DbSetSync.cs index 912c29ce..4e92feb7 100644 --- a/FreeSql.DbContext/DbSet/DbSetSync.cs +++ b/FreeSql.DbContext/DbSet/DbSetSync.cs @@ -172,8 +172,7 @@ namespace FreeSql DbContextExecCommand(); //删除没有保存的数据 var propValEach = GetItemValue(item, prop) as IEnumerable; - _db.Orm.Select().AsType(tref.RefEntityType).WhereDynamic(propValEach, true) - .ToDelete().ExecuteAffrows(); + _db.Orm.Delete().AsType(tref.RefEntityType).WhereDynamic(propValEach, true).ExecuteAffrows(); } } finally diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index b718b2e5..d9f91124 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,6 +110,13 @@ 清空状态数据 + + + 根据 lambda 条件删除数据 + + + + 添加 @@ -267,6 +274,18 @@ 此工作单元内的实体变化跟踪 + + + 正在使用中的工作单元(调试) + + + + + 开启事务后有值,是 UnitOfWork 的唯一标识 + 格式:yyyyMMdd_HHmmss_种子id + 例如:20191121_214504_1 + + 创建普通数据上下文档对象 diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index 892d5e74..4f619c71 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -1,6 +1,7 @@ using SafeObjectPool; using System; using System.Collections.Generic; +using System.Collections.Concurrent; using System.Data; using System.Data.Common; using System.Linq; @@ -14,10 +15,23 @@ namespace FreeSql public static readonly AsyncLocal Current = new AsyncLocal(); #endif + static int _seed; + /// + /// 正在使用中的工作单元(调试) + /// + public static ConcurrentDictionary DebugBeingUsed { get; } = new ConcurrentDictionary(); + protected IFreeSql _fsql; protected Object _conn; protected DbTransaction _tran; + /// + /// 开启事务后有值,是 UnitOfWork 的唯一标识 + /// 格式:yyyyMMdd_HHmmss_种子id + /// 例如:20191121_214504_1 + /// + public string Id { get; private set; } + public UnitOfWork(IFreeSql fsql) { _fsql = fsql; @@ -28,6 +42,9 @@ namespace FreeSql void ReturnObject() { + if (string.IsNullOrEmpty(this.Id) == false && DebugBeingUsed.TryRemove(this.Id, out var old)) + this.Id = null; + _fsql.Ado.MasterPool.Return(_conn); _tran = null; _conn = null; @@ -66,6 +83,9 @@ namespace FreeSql _tran = IsolationLevel == null ? _conn.Value.BeginTransaction() : _conn.Value.BeginTransaction(IsolationLevel.Value); + + this.Id = $"{DateTime.Now.ToString("yyyyMMdd_HHmmss")}_{Interlocked.Increment(ref _seed)}"; + DebugBeingUsed.TryAdd(this.Id, this); } catch { diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 6bc4b8d9..56b67dc0 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -655,11 +655,12 @@ 实体集合 - + 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + 是否标识为NOT @@ -1797,11 +1798,12 @@ 实体集合 - + 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + 是否标识为NOT diff --git a/FreeSql/Interface/Curd/IDelete.cs b/FreeSql/Interface/Curd/IDelete.cs index 127abd7a..3619cd67 100644 --- a/FreeSql/Interface/Curd/IDelete.cs +++ b/FreeSql/Interface/Curd/IDelete.cs @@ -52,8 +52,9 @@ namespace FreeSql /// 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// 是否标识为NOT /// - IDelete WhereDynamic(object dywhere); + IDelete WhereDynamic(object dywhere, bool not = false); /// /// 禁用全局过滤功能,不传参数时将禁用所有 diff --git a/FreeSql/Interface/Curd/IUpdate.cs b/FreeSql/Interface/Curd/IUpdate.cs index 2c47437d..9276c68d 100644 --- a/FreeSql/Interface/Curd/IUpdate.cs +++ b/FreeSql/Interface/Curd/IUpdate.cs @@ -121,8 +121,9 @@ namespace FreeSql /// 传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} /// /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + /// 是否标识为NOT /// - IUpdate WhereDynamic(object dywhere); + IUpdate WhereDynamic(object dywhere, bool not = false); /// /// 禁用全局过滤功能,不传参数时将禁用所有 diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index b1b740af..ed1bac84 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -96,7 +96,9 @@ namespace FreeSql.Internal.CommonProvider } public IDelete Where(T1 item) => this.Where(new[] { item }); public IDelete Where(IEnumerable items) => this.Where(_commonUtils.WhereItems(_table, "", items)); - public IDelete WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_table, "", dywhere)); + public IDelete WhereDynamic(object dywhere, bool not = false) => not == false ? + this.Where(_commonUtils.WhereObject(_table, "", dywhere)) : + this.Where($"not({_commonUtils.WhereObject(_table, "", dywhere)})"); public IDelete DisableGlobalFilter(params string[] name) { diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index 8823c5bc..51c04727 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -434,7 +434,9 @@ namespace FreeSql.Internal.CommonProvider } public IUpdate Where(T1 item) => this.Where(new[] { item }); public IUpdate Where(IEnumerable items) => this.Where(_commonUtils.WhereItems(_table, "", items)); - public IUpdate WhereDynamic(object dywhere) => this.Where(_commonUtils.WhereObject(_table, "", dywhere)); + public IUpdate WhereDynamic(object dywhere, bool not = false) => not == false ? + this.Where(_commonUtils.WhereObject(_table, "", dywhere)) : + this.Where($"not({_commonUtils.WhereObject(_table, "", dywhere)})"); public IUpdate DisableGlobalFilter(params string[] name) {