diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码(.Net 4.0).zip b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码(.Net 4.0).zip index 15569d33..11ac0871 100644 Binary files a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码(.Net 4.0).zip and b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码(.Net 4.0).zip differ diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码.zip b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码.zip index ab1fb53d..47a9b4d1 100644 Binary files a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码.zip and b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity 纯净版源码.zip differ diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs index 60ce244a..4b491433 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs @@ -1,7 +1,10 @@ using FreeSql.DataAnnotations; using System; +using System.Collections; +using System.Collections.Generic; using System.Data; using System.Diagnostics; +using System.Linq; using System.Linq.Expressions; using System.Threading; @@ -109,12 +112,47 @@ namespace FreeSql { get { - var select = Orm.Select().WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction(false)); + var select = Orm.Select() + .TrackToList(TrackToList) //自动为每个元素 Attach + .WithTransaction(UnitOfWork.Current.Value?.GetOrBeginTransaction(false)); if (string.IsNullOrEmpty(CurrentTenantId) == false) select.WhereCascade(a => (a as ITenant).TenantId == CurrentTenantId); return select.WhereCascade(a => (a as BaseEntity).IsDeleted == false); } } + + static void TrackToList(object list) + { + if (list == null) return; + var ls = list as IList; + if (ls == null) + { + var ie = list as IEnumerable; + if (ie == null) return; + var isFirst = true; + foreach (var item in ie) + { + if (item == null) return; + if (isFirst) + { + isFirst = false; + var itemType = item.GetType(); + if (itemType == typeof(object)) return; + if (itemType.FullName.StartsWith("Submission#")) itemType = itemType.BaseType; + if (Orm.CodeFirst.GetTableByEntity(itemType)?.Primarys.Any() != true) return; + if (item is BaseEntity == false) return; + } + (item as BaseEntity)?.Attach(); + } + return; + } + if (ls.Any() == false) return; + if (ls.FirstOrDefault() is BaseEntity == false) return; + if (Orm.CodeFirst.GetTableByEntity(typeof(TEntity))?.Primarys.Any() != true) return; + foreach (var item in ls) + (item as BaseEntity)?.Attach(); + } + /// /// 设置当前租户id /// diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index d9f91124..dc0203b8 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -110,13 +110,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 64a4e184..97eb81b3 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1037,7 +1037,7 @@ 设置别名规则,可用于拦截表别名,实现类似 sqlserver 的 with(nolock) 需求 - 如:select.AsAlias((_, oldAlias) => oldAlias + " with(lock)") + 如:select.AsAlias((_, old) => $"{old} with(lock)") @@ -2146,6 +2146,137 @@ + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 }) + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 }) + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 }) + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 }) + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 }) + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 }) + + + + + + + + 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new { age = 25 }) + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > @age; select * from address", new { age = 25 }) + + + + + + 可自定义解析表达式 @@ -2924,160 +3055,3 @@ -unc{``0,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})"> - - 使用 or 拼接两个 lambda 表达式 - - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 查询数据 - - - - - - - 查询数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 删除数据 - - - - - - - 删除数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步),60秒未执行完成(可能)被其他线程事务自动提交 - - 事务体 () => {} - - - - 开启事务(不支持异步) - - 超时,未执行完成(可能)被其他线程事务自动提交 - 事务体 () => {} - - - - 开启事务(不支持异步) - - - 事务体 () => {} - 超时,未执行完成(可能)被其他线程事务自动提交 - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - - diff --git a/FreeSql/Interface/Curd/ISelect/ISelect0.cs b/FreeSql/Interface/Curd/ISelect/ISelect0.cs index a9366d41..363d8249 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect0.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect0.cs @@ -124,7 +124,7 @@ namespace FreeSql TSelect AsTable(Func tableRule); /// /// 设置别名规则,可用于拦截表别名,实现类似 sqlserver 的 with(nolock) 需求 - /// 如:select.AsAlias((_, oldAlias) => oldAlias + " with(lock)") + /// 如:select.AsAlias((_, old) => $"{old} with(lock)") /// /// ///