diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 0fc4317a..2939a230 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -139,7 +139,7 @@ namespace base_entity public int TypeGuid { get; set; } public string Title { get; set; } public DateTime CreateTime { get; set; } - [Column(MapType = typeof(JArray))] + [JsonMap] public List CouponIds { get; set; } } class TopicMapTypeToListDtoMap @@ -167,7 +167,7 @@ namespace base_entity //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3;TrustServerCertificate=true") - .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") + //.UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=2") //.UseNameConvert(FreeSql.Internal.NameConvertType.ToLower) //.UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2") @@ -193,7 +193,7 @@ namespace base_entity BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion - //fsql.UseJsonMap(); + fsql.UseJsonMap(); fsql.Delete().Where("1=1").ExecuteAffrows(); fsql.Insert(new[] diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs index 8986e5b5..7664b0dd 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs @@ -80,12 +80,10 @@ namespace FreeSql { bool UpdateIsDeleted(bool value) { - if (Repository is null) - { + if (Repository == null) return Orm.Update(this as TEntity) - .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction()) - .Set(a => (a as BaseEntity).IsDeleted, IsDeleted = value).ExecuteAffrows() == 1; - } + .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction()) + .Set(a => (a as BaseEntity).IsDeleted, IsDeleted = value).ExecuteAffrows() == 1; IsDeleted = value; Repository.UnitOfWork = _resolveUow?.Invoke(); @@ -103,7 +101,7 @@ namespace FreeSql if (physicalDelete == false) return UpdateIsDeleted(true); - if (Repository is null) + if (Repository == null) return Orm.Delete(this as TEntity).ExecuteAffrows() == 1; Repository.UnitOfWork = _resolveUow?.Invoke(); @@ -125,12 +123,10 @@ namespace FreeSql public virtual bool Update() { UpdateTime = DateTime.Now; - if (Repository is null) - { + if (Repository == null) return Orm.Update() - .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction()) - .SetSource(this as TEntity).ExecuteAffrows() == 1; - } + .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction()) + .SetSource(this as TEntity).ExecuteAffrows() == 1; Repository.UnitOfWork = _resolveUow?.Invoke(); return Repository.Update(this as TEntity) == 1; @@ -143,7 +139,8 @@ namespace FreeSql public virtual TEntity Insert() { CreateTime = DateTime.Now; - Repository ??= Orm.GetRepository(); + if (Repository == null) + Repository = Orm.GetRepository(); Repository.UnitOfWork = _resolveUow?.Invoke(); return Repository.Insert(this as TEntity); } @@ -156,7 +153,8 @@ namespace FreeSql public virtual TEntity Save() { UpdateTime = DateTime.Now; - Repository ??= Orm.GetRepository(); + if (Repository == null) + Repository = Orm.GetRepository(); Repository.UnitOfWork = _resolveUow?.Invoke(); return Repository.InsertOrUpdate(this as TEntity); } @@ -168,7 +166,8 @@ namespace FreeSql /// Navigation property name public virtual void SaveMany(string navigatePropertyName) { - Repository ??= Orm.GetRepository(); + if (Repository == null) + Repository = Orm.GetRepository(); Repository.UnitOfWork = _resolveUow?.Invoke(); Repository.SaveMany(this as TEntity, navigatePropertyName); } diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs index 58f1300e..d3a9ee74 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs @@ -67,12 +67,10 @@ namespace FreeSql #if !NET40 async Task UpdateIsDeletedAsync(bool value) { - if (Repository is null) - { + if (Repository == null) return await Orm.Update(this as TEntity) - .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction()) - .Set(a => (a as BaseEntity).IsDeleted, IsDeleted = value).ExecuteAffrowsAsync() == 1; - } + .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction()) + .Set(a => (a as BaseEntity).IsDeleted, IsDeleted = value).ExecuteAffrowsAsync() == 1; IsDeleted = value; Repository.UnitOfWork = _resolveUow?.Invoke(); @@ -90,7 +88,7 @@ namespace FreeSql if (physicalDelete == false) return await UpdateIsDeletedAsync(true); - if (Repository is null) + if (Repository == null) return await Orm.Delete(this as TEntity).ExecuteAffrowsAsync() == 1; Repository.UnitOfWork = _resolveUow?.Invoke(); @@ -112,12 +110,10 @@ namespace FreeSql public virtual async Task UpdateAsync() { UpdateTime = DateTime.Now; - if (Repository is null) - { + if (Repository == null) return await Orm.Update() - .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction()) - .SetSource(this as TEntity).ExecuteAffrowsAsync() == 1; - } + .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction()) + .SetSource(this as TEntity).ExecuteAffrowsAsync() == 1; Repository.UnitOfWork = _resolveUow?.Invoke(); return await Repository.UpdateAsync(this as TEntity) == 1; @@ -130,7 +126,8 @@ namespace FreeSql public virtual Task InsertAsync() { CreateTime = DateTime.Now; - Repository ??= Orm.GetRepository(); + if (Repository == null) + Repository = Orm.GetRepository(); Repository.UnitOfWork = _resolveUow?.Invoke(); return Repository.InsertAsync(this as TEntity); } @@ -143,7 +140,8 @@ namespace FreeSql public virtual Task SaveAsync() { UpdateTime = DateTime.Now; - Repository ??= Orm.GetRepository(); + if (Repository == null) + Repository = Orm.GetRepository(); Repository.UnitOfWork = _resolveUow?.Invoke(); return Repository.InsertOrUpdateAsync(this as TEntity); } @@ -155,7 +153,8 @@ namespace FreeSql /// Navigation property name public virtual Task SaveManyAsync(string navigatePropertyName) { - Repository ??= Orm.GetRepository(); + if (Repository == null) + Repository = Orm.GetRepository(); Repository.UnitOfWork = _resolveUow?.Invoke(); return Repository.SaveManyAsync(this as TEntity, navigatePropertyName); } diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs index 8b10be63..d22e7121 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs @@ -21,48 +21,29 @@ namespace FreeSql [Table(DisableSyncStructure = true)] public abstract class BaseEntity { - internal static IFreeSql _ormPriv; - - private const string ErrorMessageTemplate = @"使用前请初始化: -BaseEntity.Initialization(new FreeSqlBuilder() - .UseAutoSyncStructure(true) - .UseConnectionString(DataType.Sqlite, ""data source=test.db;max pool size=5"") - .Build());"; - - /// - /// Global IFreeSql ORM Object
- /// 全局 IFreeSql ORM 对象 - ///
- public static IFreeSql Orm => _ormPriv ?? throw new Exception(ErrorMessageTemplate); - + static Func _resoleOrm; internal static Func _resolveUow; - /// - /// To initialize the BaseEntity
- /// 初始化 BaseEntity - /// - /// BaseEntity.Initialization(
- /// new FreeSqlBuilder()
- /// .UseAutoSyncStructure(true)
- /// .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=5")
- /// .Build()); - ///
- /// IFreeSql ORM Object - /// 工作单元(事务)委托,如果不使用事务请传 null解释:由于AsyncLocal平台兼容不好,所以交给外部管理 + public static IFreeSql Orm => _resoleOrm?.Invoke() ?? throw new Exception("BaseEntity.Initialization 初始化错误,获取到 IFreeSql 是 null"); + public static void Initialization(IFreeSql fsql, Func resolveUow) { - _ormPriv = fsql; - _ormPriv.Aop.CurdBefore += (s, e) => Trace.WriteLine($"\r\n线程{Thread.CurrentThread.ManagedThreadId}: {e.Sql}\r\n"); + fsql.Aop.CurdBefore += (s, e) => Trace.WriteLine($"\r\n线程{Thread.CurrentThread.ManagedThreadId}: {e.Sql}\r\n"); + Initialization(() => fsql, resolveUow); + } + public static void Initialization(Func resoleOrm, Func resolveUow) + { + _resoleOrm = resoleOrm; + _resolveUow = resolveUow; + if (_configEntityQueues.Any()) { lock (_configEntityLock) { while (_configEntityQueues.TryDequeue(out var cei)) - _ormPriv.CodeFirst.ConfigEntity(cei.EntityType, cei.Fluent); + Orm.CodeFirst.ConfigEntity(cei.EntityType, cei.Fluent); } } - - _resolveUow = resolveUow; } class ConfigEntityInfo @@ -71,17 +52,17 @@ BaseEntity.Initialization(new FreeSqlBuilder() public Action Fluent; } - static readonly ConcurrentQueue _configEntityQueues = new(); - static readonly object _configEntityLock = new(); + static readonly ConcurrentQueue _configEntityQueues = new ConcurrentQueue(); + static readonly object _configEntityLock = new object(); internal static void ConfigEntity(Type entityType, Action fluent) { lock (_configEntityLock) { - if (_ormPriv is null) + if (_resoleOrm?.Invoke() == null) _configEntityQueues.Enqueue(new ConfigEntityInfo { EntityType = entityType, Fluent = fluent }); else - _ormPriv.CodeFirst.ConfigEntity(entityType, fluent); + Orm.CodeFirst.ConfigEntity(entityType, fluent); } } @@ -133,69 +114,59 @@ BaseEntity.Initialization(new FreeSqlBuilder() get { var select = Orm.Select() - .TrackToList(TrackToList) //自动为每个元素 Attach - .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction(false)); + .TrackToList(TrackToList) //自动为每个元素 Attach + .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction(false)); return select.WhereCascade(a => (a as BaseEntity).IsDeleted == false); } } static void TrackToList(object list) { - if (list is null) - return; + if (list == null) return; - if (list is not IList ls) + var ls = list as IList; + if (ls == null) { - if (list is not IEnumerable ie) - return; + var ie = list as IEnumerable; + if (ie == null) return; var isFirst = true; IBaseRepository baseRepo = null; foreach (var item in ie) { - if (item is null) - { - return; - } + if (item == null) return; if (isFirst) { isFirst = false; var itemType = item.GetType(); if (itemType == typeof(object)) return; - if (itemType.FullName!.Contains("FreeSqlLazyEntity__")) itemType = itemType.BaseType; + if (itemType.FullName.Contains("FreeSqlLazyEntity__")) itemType = itemType.BaseType; if (Orm.CodeFirst.GetTableByEntity(itemType)?.Primarys.Any() != true) return; - if (item is not BaseEntity) return; + if (item is BaseEntity == false) return; } if (item is BaseEntity entity) { - baseRepo ??= Orm.GetRepository(); + if (baseRepo == null) baseRepo = Orm.GetRepository(); entity.Repository = baseRepo; entity.Attach(); } } - return; } - if (ls.Any() == false) - return; - - if (ls.FirstOrDefault() is not BaseEntity) - return; - - if (Orm.CodeFirst.GetTableByEntity(typeof(TEntity))?.Primarys.Any() != true) - return; + if (ls.Any() == false) return; + if (ls.FirstOrDefault() is BaseEntity == false) return; + if (Orm.CodeFirst.GetTableByEntity(typeof(TEntity))?.Primarys.Any() != true) return; IBaseRepository repo = null; - foreach (var item in ls) { if (item is BaseEntity entity) { - repo ??= Orm.GetRepository(); + if (repo == null) repo = Orm.GetRepository(); entity.Repository = repo; entity.Attach(); } @@ -237,7 +208,8 @@ BaseEntity.Initialization(new FreeSqlBuilder() /// public TEntity Attach() { - Repository ??= Orm.GetRepository(); + if (Repository == null) + Repository = Orm.GetRepository(); var item = this as TEntity; Repository.Attach(item); return item; diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml index 254706c1..f5d4630c 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.xml @@ -173,26 +173,6 @@ 包括 CreateTime/UpdateTime/IsDeleted 的实体基类 - - - Global IFreeSql ORM Object
- 全局 IFreeSql ORM 对象 -
-
- - - To initialize the BaseEntity
- 初始化 BaseEntity - - BaseEntity.Initialization(
- new FreeSqlBuilder()
- .UseAutoSyncStructure(true)
- .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=5")
- .Build()); -
- IFreeSql ORM Object - 工作单元(事务)委托,如果不使用事务请传 null解释:由于AsyncLocal平台兼容不好,所以交给外部管理 -
Created time
diff --git a/Extensions/FreeSql.Extensions.BaseEntity/README.zh-CN.MD b/Extensions/FreeSql.Extensions.BaseEntity/README.zh-CN.MD index 4314961b..4dd0c551 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/README.zh-CN.MD +++ b/Extensions/FreeSql.Extensions.BaseEntity/README.zh-CN.MD @@ -95,6 +95,17 @@ var items = UserGroup.Where(a => a.Id > 10).ToList(); # 事务建议 +1、同线程事务,不支持异步: + +```c# +fsql.Transaction(() => +{ + //todo ... +}) +```; + +2、如果你是异步控 + 由于 AsyncLocal 平台兼容不好,所以交给外部管理事务。 ```csharp @@ -103,7 +114,7 @@ static AsyncLocal _asyncUow = new AsyncLocal(); BaseEntity.Initialization(fsql, () => _asyncUow.Value); ``` -在 Scoped 开始时: _asyncUow.Value = fsql.CreateUnitOfWork(); (也可以使用 UnitOfWorkManager 对象获取 uow) +在 Scoped 开始时:_asyncUow.Value = fsql.CreateUnitOfWork(); (也可以使用 UnitOfWorkManager 对象获取 uow) 在 Scoped 结束时:_asyncUow.Value = null; diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 6408f09d..e6a05c06 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -4899,3 +4899,222 @@ +ystem.Boolean}})"> + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 使用 and 拼接两个 lambda 表达式 + + + + + + 使用 and 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + + + + 使用 or 拼接两个 lambda 表达式 + + + true 时生效 + + + + + + 将 lambda 表达式取反 + + + true 时生效 + + + + + 生成类似Mongodb的ObjectId有序、不重复Guid + + + + + + 插入数据 + + + + + + + 插入数据,传入实体 + + + + + + + + 插入数据,传入实体数组 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + MySql 5.6+: on duplicate key update + PostgreSQL 9.4+: on conflict do update + SqlServer 2008+: merge into + Oracle 11+: merge into + Sqlite: replace into + 达梦: merge into + 人大金仓:on conflict do update + 神通:merge into + MsAccess:不支持 + 注意区别:FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性) + + + + + + + 修改数据 + + + + + + + 修改数据,传入动态条件,如:主键值 | 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} + + + 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 + + + + + 开启事务(不支持异步) + v1.5.0 关闭了线程事务超时自动提交的机制 + + 事务体 () => {} + + + + 开启事务(不支持异步) + v1.5.0 关闭了线程事务超时自动提交的机制 + + + 事务体 () => {} + + + + 数据库访问对象 + + + + + 所有拦截方法都在这里 + + + + + CodeFirst 模式开发相关方法 + + + + + DbFirst 模式开发相关方法 + + + + + 全局过滤设置,可默认附加为 Select/Update/Delete 条件 + + + +