From ebd962b8271e3c066710de8227d7d2881a1d4f5f Mon Sep 17 00:00:00 2001 From: DMKun Date: Thu, 15 Jul 2021 00:33:04 +0800 Subject: [PATCH 01/19] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E9=BB=98=E8=AE=A4=E5=80=BC=E4=B8=BA'\'=E7=AD=89?= =?UTF-8?q?=E8=BD=AC=E4=B9=89=E5=AD=97=E7=AC=A6=E5=AF=BC=E8=87=B4=E7=94=9F?= =?UTF-8?q?=E6=88=90=E7=9A=84=E5=AE=9E=E4=BD=93=E6=97=A0=E6=B3=95=E9=80=9A?= =?UTF-8?q?=E8=BF=87=E7=BC=96=E8=AF=91bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 生成的字符串格式多一个@符,在模板文件中无法判定当前生成的字段为string类型,因此修改代码实现修复转义字符bug [JsonProperty, Column(DbType = "NVARCHAR", IsPrimary = true, IsNullable = false)] public string syscfg_ID { get; set; } = @""; --- Extensions/FreeSql.Generator/RazorModel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/FreeSql.Generator/RazorModel.cs b/Extensions/FreeSql.Generator/RazorModel.cs index e21d2deb..326724de 100644 --- a/Extensions/FreeSql.Generator/RazorModel.cs +++ b/Extensions/FreeSql.Generator/RazorModel.cs @@ -253,7 +253,7 @@ public class RazorModel if (cstype == typeof(Guid) && Guid.TryParse(defval, out var tryguid)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"Guid.Parse(\"{defval.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")}\")"; if (cstype == typeof(DateTime) && DateTime.TryParse(defval, out var trydt)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"DateTime.Parse(\"{defval.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")}\")"; if (cstype == typeof(TimeSpan) && TimeSpan.TryParse(defval, out var tryts)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"TimeSpan.Parse(\"{defval.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")}\")"; - if (cstype == typeof(string)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"\"{defval.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")}\""; + if (cstype == typeof(string)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"@\"{defval.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")}\""; if (cstype == typeof(bool)) return isInsertValueSql ? defval : (defval == "1" || defval == "t" ? "true" : "false"); if (fsql.Ado.DataType == DataType.MySql || fsql.Ado.DataType == DataType.OdbcMySql) if (col.DbType == (int)MySqlDbType.Enum || col.DbType == (int)MySqlDbType.Set) From 6e5ef1e090a00a0bd707a83a76575d9e30c89961 Mon Sep 17 00:00:00 2001 From: IGeekFan Date: Fri, 30 Jul 2021 10:05:56 +0800 Subject: [PATCH 02/19] Fix Exception Message --- Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs index a7dd41e5..0ef9e5d8 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessProvider.cs @@ -15,7 +15,7 @@ namespace FreeSql.MsAccess public override IDelete CreateDeleteProvider(object dywhere) => new MsAccessDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); public override IInsertOrUpdate CreateInsertOrUpdateProvider() => throw new NotImplementedException(); - public override IDbFirst DbFirst => throw new NotImplementedException("FreeSql.Provider.Sqlite 未实现该功能"); + public override IDbFirst DbFirst => throw new NotImplementedException("FreeSql.Provider.MsAccess 未实现该功能"); public MsAccessProvider(string masterConnectionString, string[] slaveConnectionString, Func connectionFactory = null) { this.InternalCommonUtils = new MsAccessUtils(this); From 5dd8210653731fa0429f59591a9d2ddc13036cde Mon Sep 17 00:00:00 2001 From: AlexLEWIS Date: Fri, 6 Aug 2021 16:55:44 +0800 Subject: [PATCH 03/19] Code cleanup. --- .../BaseEntity.cs | 95 +++++++++------- .../BaseEntityAsync.cs | 103 ++++++++++-------- .../BaseEntityReadOnly.cs | 84 ++++++++------ .../FreeSql.Extensions.BaseEntity.csproj | 5 +- 4 files changed, 164 insertions(+), 123 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs index 40382f84..76d2d2a5 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs @@ -1,12 +1,15 @@ -using FreeSql; +#if NET40 +using FreeSql.DataAnnotations; +using System; + +#else using FreeSql.DataAnnotations; using System; -using System.Data; -using System.Diagnostics; -using System.Linq.Expressions; -using System.Threading; using System.Threading.Tasks; +#endif + +// ReSharper disable once CheckNamespace namespace FreeSql { /// @@ -21,9 +24,9 @@ namespace FreeSql { static BaseEntity() { - var tkeyType = typeof(TKey)?.NullableTypeOrThis(); - if (tkeyType == typeof(int) || tkeyType == typeof(long)) - BaseEntity.ConfigEntity(typeof(TEntity), t => t.Property("Id").IsIdentity(true)); + var keyType = typeof(TKey).NullableTypeOrThis(); + if (keyType == typeof(int) || keyType == typeof(long)) + ConfigEntity(typeof(TEntity), t => t.Property("Id").IsIdentity(true)); } /// @@ -32,14 +35,13 @@ namespace FreeSql [Column(Position = 1)] public virtual TKey Id { get; set; } -#if net40 -#else +#if !NET40 /// /// 根据主键值获取数据 /// /// /// - async public static Task FindAsync(TKey id) + public static async Task FindAsync(TKey id) { var item = await Select.WhereDynamic(id).FirstAsync(); (item as BaseEntity)?.Attach(); @@ -69,15 +71,18 @@ namespace FreeSql { bool UpdateIsDeleted(bool value) { - if (this.Repository == null) + if (Repository is null) + { return Orm.Update(this as TEntity) - .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction()) - .Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrows() == 1; + .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction()) + .Set(a => (a as BaseEntity).IsDeleted, IsDeleted = value).ExecuteAffrows() == 1; + } - this.IsDeleted = value; - this.Repository.UnitOfWork = _resolveUow?.Invoke(); - return this.Repository.Update(this as TEntity) == 1; + IsDeleted = value; + Repository.UnitOfWork = _resolveUow?.Invoke(); + return Repository.Update(this as TEntity) == 1; } + /// /// 删除数据 /// @@ -85,18 +90,21 @@ namespace FreeSql /// public virtual bool Delete(bool physicalDelete = false) { - if (physicalDelete == false) return this.UpdateIsDeleted(true); - if (this.Repository == null) + if (physicalDelete == false) + return UpdateIsDeleted(true); + + if (Repository is null) return Orm.Delete(this as TEntity).ExecuteAffrows() == 1; - this.Repository.UnitOfWork = _resolveUow?.Invoke(); - return this.Repository.Delete(this as TEntity) == 1; + Repository.UnitOfWork = _resolveUow?.Invoke(); + return Repository.Delete(this as TEntity) == 1; } + /// /// 恢复删除的数据 /// /// - public virtual bool Restore() => this.UpdateIsDeleted(false); + public virtual bool Restore() => UpdateIsDeleted(false); /// /// 更新数据 @@ -104,26 +112,29 @@ namespace FreeSql /// public virtual bool Update() { - this.UpdateTime = DateTime.Now; - if (this.Repository == null) + UpdateTime = DateTime.Now; + if (Repository is null) + { return Orm.Update() - .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction()) - .SetSource(this as TEntity).ExecuteAffrows() == 1; + .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction()) + .SetSource(this as TEntity).ExecuteAffrows() == 1; + } - this.Repository.UnitOfWork = _resolveUow?.Invoke(); - return this.Repository.Update(this as TEntity) == 1; + Repository.UnitOfWork = _resolveUow?.Invoke(); + return Repository.Update(this as TEntity) == 1; } + /// /// 插入数据 /// public virtual TEntity Insert() { - this.CreateTime = DateTime.Now; - if (this.Repository == null) - this.Repository = Orm.GetRepository(); + CreateTime = DateTime.Now; + if (Repository is null) + Repository = Orm.GetRepository(); - this.Repository.UnitOfWork = _resolveUow?.Invoke(); - return this.Repository.Insert(this as TEntity); + Repository.UnitOfWork = _resolveUow?.Invoke(); + return Repository.Insert(this as TEntity); } /// @@ -132,12 +143,12 @@ namespace FreeSql /// public virtual TEntity Save() { - this.UpdateTime = DateTime.Now; - if (this.Repository == null) - this.Repository = Orm.GetRepository(); + UpdateTime = DateTime.Now; + if (Repository is null) + Repository = Orm.GetRepository(); - this.Repository.UnitOfWork = _resolveUow?.Invoke(); - return this.Repository.InsertOrUpdate(this as TEntity); + Repository.UnitOfWork = _resolveUow?.Invoke(); + return Repository.InsertOrUpdate(this as TEntity); } /// @@ -146,11 +157,11 @@ namespace FreeSql /// 导航属性名 public virtual void SaveMany(string navigatePropertyName) { - if (this.Repository == null) - this.Repository = Orm.GetRepository(); + if (Repository is null) + Repository = Orm.GetRepository(); - this.Repository.UnitOfWork = _resolveUow?.Invoke(); - this.Repository.SaveMany(this as TEntity, navigatePropertyName); + Repository.UnitOfWork = _resolveUow?.Invoke(); + Repository.SaveMany(this as TEntity, navigatePropertyName); } } } \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs index ca589470..3821a812 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs @@ -1,9 +1,14 @@ - -using FreeSql; +#if NET40 +using FreeSql.DataAnnotations; + +#else using FreeSql.DataAnnotations; using System; using System.Threading.Tasks; +#endif + +// ReSharper disable once CheckNamespace namespace FreeSql { /// @@ -18,32 +23,30 @@ namespace FreeSql { static BaseEntityAsync() { - var tkeyType = typeof(TKey)?.NullableTypeOrThis(); - if (tkeyType == typeof(int) || tkeyType == typeof(long)) - BaseEntity.ConfigEntity(typeof(TEntity), t => t.Property("Id").IsIdentity(true)); + var keyType = typeof(TKey).NullableTypeOrThis(); + if (keyType == typeof(int) || keyType == typeof(long)) + ConfigEntity(typeof(TEntity), t => t.Property("Id").IsIdentity(true)); } /// /// 主键 /// - [Column(Position = 1)] + [Column(Position = 1)] public virtual TKey Id { get; set; } -#if net40 -#else +#if !NET40 /// /// 根据主键值获取数据 /// /// /// - async public static Task FindAsync(TKey id) + public static async Task FindAsync(TKey id) { var item = await Select.WhereDynamic(id).FirstAsync(); (item as BaseEntity)?.Attach(); return item; } #endif - } /// @@ -53,65 +56,73 @@ namespace FreeSql [Table(DisableSyncStructure = true)] public abstract class BaseEntityAsync : BaseEntityReadOnly where TEntity : class { -#if net40 -#else +#if !NET40 async Task UpdateIsDeletedAsync(bool value) { - if (this.Repository == null) + if (Repository is null) + { return await Orm.Update(this as TEntity) - .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction()) - .Set(a => (a as BaseEntity).IsDeleted, this.IsDeleted = value).ExecuteAffrowsAsync() == 1; + .WithTransaction(_resolveUow?.Invoke()?.GetOrBeginTransaction()) + .Set(a => (a as BaseEntity).IsDeleted, IsDeleted = value).ExecuteAffrowsAsync() == 1; + } - this.IsDeleted = value; - this.Repository.UnitOfWork = _resolveUow?.Invoke(); - return await this.Repository.UpdateAsync(this as TEntity) == 1; + IsDeleted = value; + Repository.UnitOfWork = _resolveUow?.Invoke(); + return await Repository.UpdateAsync(this as TEntity) == 1; } + /// /// 删除数据 /// /// 是否物理删除 /// - async public virtual Task DeleteAsync(bool physicalDelete = false) + public virtual async Task DeleteAsync(bool physicalDelete = false) { - if (physicalDelete == false) return await this.UpdateIsDeletedAsync(true); - if (this.Repository == null) + if (physicalDelete == false) + return await UpdateIsDeletedAsync(true); + + if (Repository is null) return await Orm.Delete(this as TEntity).ExecuteAffrowsAsync() == 1; - this.Repository.UnitOfWork = _resolveUow?.Invoke(); - return await this.Repository.DeleteAsync(this as TEntity) == 1; + Repository.UnitOfWork = _resolveUow?.Invoke(); + return await Repository.DeleteAsync(this as TEntity) == 1; } + /// /// 恢复删除的数据 /// /// - public virtual Task RestoreAsync() => this.UpdateIsDeletedAsync(false); + public virtual Task RestoreAsync() => UpdateIsDeletedAsync(false); /// /// 更新数据 /// /// - async public virtual Task UpdateAsync() + public virtual async Task UpdateAsync() { - this.UpdateTime = DateTime.Now; - if (this.Repository == null) + UpdateTime = DateTime.Now; + if (Repository is 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; + } - this.Repository.UnitOfWork = _resolveUow?.Invoke(); - return await this.Repository.UpdateAsync(this as TEntity) == 1; + Repository.UnitOfWork = _resolveUow?.Invoke(); + return await Repository.UpdateAsync(this as TEntity) == 1; } + /// /// 插入数据 /// public virtual Task InsertAsync() { - this.CreateTime = DateTime.Now; - if (this.Repository == null) - this.Repository = Orm.GetRepository(); + CreateTime = DateTime.Now; + if (Repository is null) + Repository = Orm.GetRepository(); - this.Repository.UnitOfWork = _resolveUow?.Invoke(); - return this.Repository.InsertAsync(this as TEntity); + Repository.UnitOfWork = _resolveUow?.Invoke(); + return Repository.InsertAsync(this as TEntity); } /// @@ -120,12 +131,12 @@ namespace FreeSql /// public virtual Task SaveAsync() { - this.UpdateTime = DateTime.Now; - if (this.Repository == null) - this.Repository = Orm.GetRepository(); + UpdateTime = DateTime.Now; + if (Repository is null) + Repository = Orm.GetRepository(); - this.Repository.UnitOfWork = _resolveUow?.Invoke(); - return this.Repository.InsertOrUpdateAsync(this as TEntity); + Repository.UnitOfWork = _resolveUow?.Invoke(); + return Repository.InsertOrUpdateAsync(this as TEntity); } /// @@ -134,12 +145,12 @@ namespace FreeSql /// 导航属性名 public virtual Task SaveManyAsync(string navigatePropertyName) { - if (this.Repository == null) - this.Repository = Orm.GetRepository(); + if (Repository is null) + Repository = Orm.GetRepository(); - this.Repository.UnitOfWork = _resolveUow?.Invoke(); - return this.Repository.SaveManyAsync(this as TEntity, navigatePropertyName); + Repository.UnitOfWork = _resolveUow?.Invoke(); + return Repository.SaveManyAsync(this as TEntity, navigatePropertyName); } #endif } -} +} \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs index b3dd1c8a..13c44e92 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs @@ -1,15 +1,14 @@ - -using FreeSql.DataAnnotations; +using FreeSql.DataAnnotations; using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Data.Common; using System.Diagnostics; using System.Linq; using System.Linq.Expressions; using System.Threading; +// ReSharper disable once CheckNamespace namespace FreeSql { /// @@ -19,6 +18,7 @@ namespace FreeSql public abstract class BaseEntity { internal static IFreeSql _ormPriv; + /// /// 全局 IFreeSql orm 对象 /// @@ -26,6 +26,7 @@ namespace FreeSql .UseAutoSyncStructure(true) .UseConnectionString(DataType.Sqlite, ""data source=test.db;max pool size=5"") .Build());"); + internal static Func _resolveUow; /// @@ -52,21 +53,24 @@ namespace FreeSql _ormPriv.CodeFirst.ConfigEntity(cei.EntityType, cei.Fluent); } } + _resolveUow = resolveUow; } - + class ConfigEntityInfo { public Type EntityType; public Action Fluent; } - static ConcurrentQueue _configEntityQueues = new ConcurrentQueue(); - static object _configEntityLock = new object(); + + static ConcurrentQueue _configEntityQueues = new(); + static object _configEntityLock = new(); + internal static void ConfigEntity(Type entityType, Action fluent) { lock (_configEntityLock) { - if (_ormPriv == null) + if (_ormPriv is null) _configEntityQueues.Enqueue(new ConfigEntityInfo { EntityType = entityType, Fluent = fluent }); else _ormPriv.CodeFirst.ConfigEntity(entityType, fluent); @@ -78,16 +82,19 @@ namespace FreeSql /// [Column(Position = -4)] public virtual DateTime CreateTime { get; set; } = DateTime.Now; + /// /// 更新时间 /// [Column(Position = -3)] public virtual DateTime UpdateTime { get; set; } + /// /// 逻辑删除 /// [Column(Position = -2)] public virtual bool IsDeleted { get; set; } + /// /// 排序 /// @@ -107,25 +114,29 @@ namespace FreeSql 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 == null) return; - var ls = list as IList; - if (ls == null) + if (list is null) + return; + + if (list is not IList ls) { - var ie = list as IEnumerable; - if (ie == null) return; + if (list is not IEnumerable ie) + return; + var isFirst = true; + IBaseRepository berepo = null; + foreach (var item in ie) { - if (item == null) return; + if (item is null) return; if (isFirst) { isFirst = false; @@ -135,28 +146,36 @@ namespace FreeSql if (Orm.CodeFirst.GetTableByEntity(itemType)?.Primarys.Any() != true) return; if (item is BaseEntity == false) return; } - var beitem = item as BaseEntity; - if (beitem != null) + + if (item is BaseEntity entity) { - if (berepo == null) berepo = Orm.GetRepository(); - beitem.Repository = berepo; - beitem.Attach(); + berepo ??= Orm.GetRepository(); + entity.Repository = berepo; + entity.Attach(); } } + return; } - if (ls.Any() == false) return; - if (ls.FirstOrDefault() is BaseEntity == false) return; - if (Orm.CodeFirst.GetTableByEntity(typeof(TEntity))?.Primarys.Any() != true) return; + + if (ls.Any() == false) + return; + + if (ls.FirstOrDefault() is not BaseEntity) + return; + + if (Orm.CodeFirst.GetTableByEntity(typeof(TEntity))?.Primarys.Any() != true) + return; + IBaseRepository repo = null; + foreach (var item in ls) { - var beitem = item as BaseEntity; - if (beitem != null) + if (item is BaseEntity entity) { - if (repo == null) repo = Orm.GetRepository(); - beitem.Repository = repo; - beitem.Attach(); + repo ??= Orm.GetRepository(); + entity.Repository = repo; + entity.Attach(); } } } @@ -167,6 +186,7 @@ namespace FreeSql /// lambda表达式 /// public static ISelect Where(Expression> exp) => Select.Where(exp); + /// /// 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") /// @@ -185,12 +205,10 @@ namespace FreeSql /// public TEntity Attach() { - if (this.Repository == null) - this.Repository = Orm.GetRepository(); - + Repository ??= Orm.GetRepository(); var item = this as TEntity; - this.Repository.Attach(item); + Repository.Attach(item); return item; } } -} +} \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj index bfd13274..8a9e2002 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj +++ b/Extensions/FreeSql.Extensions.BaseEntity/FreeSql.Extensions.BaseEntity.csproj @@ -6,8 +6,8 @@ true FreeSql;ncc;YeXiangQin BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用. - https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.BaseEntity - https://github.com/2881099/FreeSql/tree/master/Extensions/FreeSql.Extensions.BaseEntity + https://github.com/dotnetcore/FreeSql/tree/master/Extensions/FreeSql.Extensions.BaseEntity + https://github.com/dotnetcore/FreeSql/tree/master/Extensions/FreeSql.Extensions.BaseEntity git MIT FreeSql;ORM;BaseEntity @@ -19,6 +19,7 @@ true key.snk false + latest From 73d2bfc680da517b626e11b9c4fc75429aa44dd9 Mon Sep 17 00:00:00 2001 From: AlexLEWIS Date: Fri, 6 Aug 2021 17:07:36 +0800 Subject: [PATCH 04/19] Code cleanup. --- .../BaseEntityReadOnly.cs | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs index 13c44e92..da2475d1 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs @@ -8,7 +8,9 @@ using System.Linq; using System.Linq.Expressions; using System.Threading; -// ReSharper disable once CheckNamespace +// ReSharper disable CheckNamespace +// ReSharper disable InconsistentNaming +// ReSharper disable InconsistentlySynchronizedField namespace FreeSql { /// @@ -19,13 +21,16 @@ namespace FreeSql { 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());"; + /// /// 全局 IFreeSql orm 对象 /// - public static IFreeSql Orm => _ormPriv ?? throw new Exception(@"使用前请初始化 BaseEntity.Initialization(new FreeSqlBuilder() -.UseAutoSyncStructure(true) -.UseConnectionString(DataType.Sqlite, ""data source=test.db;max pool size=5"") -.Build());"); + public static IFreeSql Orm => _ormPriv ?? throw new Exception(ErrorMessageTemplate); internal static Func _resolveUow; @@ -63,8 +68,8 @@ namespace FreeSql public Action Fluent; } - static ConcurrentQueue _configEntityQueues = new(); - static object _configEntityLock = new(); + static readonly ConcurrentQueue _configEntityQueues = new(); + static readonly object _configEntityLock = new(); internal static void ConfigEntity(Type entityType, Action fluent) { @@ -131,26 +136,29 @@ namespace FreeSql return; var isFirst = true; - - IBaseRepository berepo = null; + IBaseRepository baseRepo = null; foreach (var item in ie) { - if (item is null) return; + if (item is 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 BaseEntity == false) return; + if (item is not BaseEntity) return; } if (item is BaseEntity entity) { - berepo ??= Orm.GetRepository(); - entity.Repository = berepo; + baseRepo ??= Orm.GetRepository(); + entity.Repository = baseRepo; entity.Attach(); } } From 6789c3f3ee69d200e73b245c49c83f2f7608a54a Mon Sep 17 00:00:00 2001 From: AlexLEWIS Date: Fri, 6 Aug 2021 17:23:52 +0800 Subject: [PATCH 05/19] Add English comments. --- .../BaseEntity.cs | 31 ++++++++++++------- .../BaseEntityAsync.cs | 30 +++++++++++------- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs index 76d2d2a5..8986e5b5 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntity.cs @@ -13,8 +13,12 @@ using System.Threading.Tasks; namespace FreeSql { /// + /// Entity base class, including CreateTime/UpdateTime/IsDeleted, the CRUD methods, and ID primary key definition. + /// /// 包括 CreateTime/UpdateTime/IsDeleted、CRUD 方法、以及 ID 主键定义 的实体基类 /// + /// When TKey is int/long, the Id is set to be an auto-incremented primary key + /// /// 当 TKey 为 int/long 时,Id 主键被设为自增值主键 /// /// @@ -30,6 +34,7 @@ namespace FreeSql } /// + /// Primary key
/// 主键 ///
[Column(Position = 1)] @@ -37,6 +42,7 @@ namespace FreeSql #if !NET40 /// + /// Get data based on the value of the primary key
/// 根据主键值获取数据 ///
/// @@ -50,6 +56,7 @@ namespace FreeSql #endif /// + /// Get data based on the value of the primary key
/// 根据主键值获取数据 ///
/// @@ -63,6 +70,8 @@ namespace FreeSql } /// + /// Entity base class, including CreateTime/UpdateTime/IsDeleted, and sync/async CRUD methods. + /// /// 包括 CreateTime/UpdateTime/IsDeleted、以及 CRUD 异步和同步方法的实体基类 /// /// @@ -84,9 +93,10 @@ namespace FreeSql } /// + /// To delete data
/// 删除数据 ///
- /// 是否物理删除 + /// To flag whether to delete the physical level of the data /// public virtual bool Delete(bool physicalDelete = false) { @@ -101,12 +111,14 @@ namespace FreeSql } /// + /// To recover deleted data
/// 恢复删除的数据 ///
/// public virtual bool Restore() => UpdateIsDeleted(false); /// + /// To update data
/// 更新数据 ///
/// @@ -125,41 +137,38 @@ namespace FreeSql } /// + /// To insert data
/// 插入数据 ///
public virtual TEntity Insert() { CreateTime = DateTime.Now; - if (Repository is null) - Repository = Orm.GetRepository(); - + Repository ??= Orm.GetRepository(); Repository.UnitOfWork = _resolveUow?.Invoke(); return Repository.Insert(this as TEntity); } /// + /// To insert or update data
/// 更新或插入 ///
/// public virtual TEntity Save() { UpdateTime = DateTime.Now; - if (Repository is null) - Repository = Orm.GetRepository(); - + Repository ??= Orm.GetRepository(); Repository.UnitOfWork = _resolveUow?.Invoke(); return Repository.InsertOrUpdate(this as TEntity); } /// + /// To completely save the navigation properties of the entity in the form of sub-tables.
/// 【完整】保存导航属性,子表 ///
- /// 导航属性名 + /// Navigation property name public virtual void SaveMany(string navigatePropertyName) { - if (Repository is null) - Repository = Orm.GetRepository(); - + 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 3821a812..58f1300e 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityAsync.cs @@ -12,8 +12,12 @@ using System.Threading.Tasks; namespace FreeSql { /// + /// Entity base class, including CreateTime/UpdateTime/IsDeleted, the async CRUD methods, and ID primary key definition. + /// /// 包括 CreateTime/UpdateTime/IsDeleted、CRUD 异步方法、以及 ID 主键定义 的实体基类 /// + /// When TKey is int/long, the Id is set to be an auto-incremented primary key + /// /// 当 TKey 为 int/long 时,Id 主键被设为自增值主键 /// /// @@ -29,6 +33,7 @@ namespace FreeSql } /// + /// Primary key
/// 主键 ///
[Column(Position = 1)] @@ -36,6 +41,7 @@ namespace FreeSql #if !NET40 /// + /// Get data based on the value of the primary key
/// 根据主键值获取数据 ///
/// @@ -50,6 +56,8 @@ namespace FreeSql } /// + /// Entity base class, including CreateTime/UpdateTime/IsDeleted, and async CRUD methods. + /// /// 包括 CreateTime/UpdateTime/IsDeleted、以及 CRUD 异步方法的实体基类 /// /// @@ -72,9 +80,10 @@ namespace FreeSql } /// + /// To delete data
/// 删除数据 ///
- /// 是否物理删除 + /// To flag whether to delete the physical level of the data /// public virtual async Task DeleteAsync(bool physicalDelete = false) { @@ -89,12 +98,14 @@ namespace FreeSql } /// + /// To recover deleted data
/// 恢复删除的数据 ///
/// public virtual Task RestoreAsync() => UpdateIsDeletedAsync(false); /// + /// To update data
/// 更新数据 ///
/// @@ -113,41 +124,38 @@ namespace FreeSql } /// + /// To insert data
/// 插入数据 ///
public virtual Task InsertAsync() { CreateTime = DateTime.Now; - if (Repository is null) - Repository = Orm.GetRepository(); - + Repository ??= Orm.GetRepository(); Repository.UnitOfWork = _resolveUow?.Invoke(); return Repository.InsertAsync(this as TEntity); } /// + /// To insert or update data
/// 更新或插入 ///
/// public virtual Task SaveAsync() { UpdateTime = DateTime.Now; - if (Repository is null) - Repository = Orm.GetRepository(); - + Repository ??= Orm.GetRepository(); Repository.UnitOfWork = _resolveUow?.Invoke(); return Repository.InsertOrUpdateAsync(this as TEntity); } /// + /// To completely save the navigation properties of the entity in the form of sub-tables.
/// 【完整】保存导航属性,子表 ///
- /// 导航属性名 + /// Navigation property name public virtual Task SaveManyAsync(string navigatePropertyName) { - if (Repository is null) - Repository = Orm.GetRepository(); - + Repository ??= Orm.GetRepository(); Repository.UnitOfWork = _resolveUow?.Invoke(); return Repository.SaveManyAsync(this as TEntity, navigatePropertyName); } From 902f1e45f13b8cf810d89ee19b10e2fbb5a68210 Mon Sep 17 00:00:00 2001 From: AlexLEWIS Date: Sun, 8 Aug 2021 22:26:10 +0800 Subject: [PATCH 06/19] Add English comments. --- .../BaseEntityReadOnly.cs | 48 ++++++++++++++----- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs index da2475d1..8b10be63 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs +++ b/Extensions/FreeSql.Extensions.BaseEntity/BaseEntityReadOnly.cs @@ -14,6 +14,8 @@ using System.Threading; namespace FreeSql { /// + /// Entity base class, including CreateTime/UpdateTime/IsDeleted. + /// /// 包括 CreateTime/UpdateTime/IsDeleted 的实体基类 /// [Table(DisableSyncStructure = true)] @@ -28,23 +30,24 @@ BaseEntity.Initialization(new FreeSqlBuilder() .Build());"; /// - /// 全局 IFreeSql orm 对象 + /// Global IFreeSql ORM Object
+ /// 全局 IFreeSql ORM 对象 ///
public static IFreeSql Orm => _ormPriv ?? throw new Exception(ErrorMessageTemplate); internal static Func _resolveUow; /// - /// 初始化BaseEntity - /// BaseEntity.Initialization(new FreeSqlBuilder() + /// To initialize the BaseEntity
+ /// 初始化 BaseEntity /// - /// .UseAutoSyncStructure(true) - /// - /// .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=5") - /// - /// .Build()); + /// BaseEntity.Initialization(
+ /// new FreeSqlBuilder()
+ /// .UseAutoSyncStructure(true)
+ /// .UseConnectionString(DataType.Sqlite, "data source=test.db;max pool size=5")
+ /// .Build()); ///
- /// IFreeSql orm 对象 + /// IFreeSql ORM Object /// 工作单元(事务)委托,如果不使用事务请传 null解释:由于AsyncLocal平台兼容不好,所以交给外部管理 public static void Initialization(IFreeSql fsql, Func resolveUow) { @@ -83,34 +86,45 @@ BaseEntity.Initialization(new FreeSqlBuilder() } /// + /// Created time
/// 创建时间 ///
[Column(Position = -4)] public virtual DateTime CreateTime { get; set; } = DateTime.Now; /// + /// Updated time
/// 更新时间 ///
[Column(Position = -3)] public virtual DateTime UpdateTime { get; set; } /// + /// Logical Delete
/// 逻辑删除 ///
[Column(Position = -2)] public virtual bool IsDeleted { get; set; } /// + /// Sort
/// 排序 ///
[Column(Position = -1)] public virtual int Sort { get; set; } } + /// + /// A readonly entity base class, including CreateTime/UpdateTime/IsDeleted. + /// + /// 包括 CreateTime/UpdateTime/IsDeleted 的只读实体基类 + /// + /// [Table(DisableSyncStructure = true)] public abstract class BaseEntityReadOnly : BaseEntity where TEntity : class { /// + /// To query data
/// 查询数据 ///
/// @@ -189,14 +203,22 @@ BaseEntity.Initialization(new FreeSqlBuilder() } /// - /// 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") + /// Query conditions
+ /// 查询条件,Where(a => a.Id> 10) + /// + /// Support navigation object query
+ /// 支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") ///
/// lambda表达式 /// public static ISelect Where(Expression> exp) => Select.Where(exp); /// - /// 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") + /// Query conditions
+ /// 查询条件,Where(true, a => a.Id > 10) + /// + /// Support navigation object query
+ /// 支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") ///
/// true 时生效 /// lambda表达式 @@ -204,12 +226,14 @@ BaseEntity.Initialization(new FreeSqlBuilder() public static ISelect WhereIf(bool condition, Expression> exp) => Select.WhereIf(condition, exp); /// + /// Repository object.
/// 仓储对象 ///
protected IBaseRepository Repository { get; set; } /// - /// 附加实体,在更新数据时,只更新变化的部分 + /// To Attach entities. When updating data, only the changed part is updated.
+ /// 附加实体。在更新数据时,只更新变化的部分 ///
public TEntity Attach() { From 39ac2d8286b93646f95dfa9280322ce7b49ac832 Mon Sep 17 00:00:00 2001 From: AlexLEWIS Date: Wed, 11 Aug 2021 13:38:06 +0800 Subject: [PATCH 07/19] Add English comments for JsonMap extension package. --- .../DataAnnotations/JsonMapAttribute.cs | 12 +++++------- Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs | 11 +++++------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/Extensions/FreeSql.Extensions.JsonMap/DataAnnotations/JsonMapAttribute.cs b/Extensions/FreeSql.Extensions.JsonMap/DataAnnotations/JsonMapAttribute.cs index 44f5d8a1..77878720 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/DataAnnotations/JsonMapAttribute.cs +++ b/Extensions/FreeSql.Extensions.JsonMap/DataAnnotations/JsonMapAttribute.cs @@ -1,13 +1,11 @@ using System; -using System.Linq; +// ReSharper disable once CheckNamespace namespace FreeSql.DataAnnotations { - /// - /// 当实体类属性为【对象】时,以JSON形式映射存储 + /// When the entity class property is , map storage in JSON format.
+ /// 当实体类属性为【对象】时,以 JSON 形式映射存储 ///
- public class JsonMapAttribute : Attribute - { - } -} + public class JsonMapAttribute : Attribute { } +} \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs index 42c61462..60b0e0b1 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs +++ b/Extensions/FreeSql.Extensions.JsonMap/JsonMapCore.cs @@ -5,7 +5,6 @@ using System.Collections.Concurrent; using System.Linq; using System.Linq.Expressions; using System.Reflection; -using System.Text; using System.Threading; public static class FreeSqlJsonMapCoreExtensions @@ -19,11 +18,12 @@ public static class FreeSqlJsonMapCoreExtensions public static ColumnFluent JsonMap(this ColumnFluent col) { _dicJsonMapFluentApi.GetOrAdd(col._entityType, et => new ConcurrentDictionary()) - .GetOrAdd(col._property.Name, pn => true); + .GetOrAdd(col._property.Name, pn => true); return col; } /// + /// When the entity class property is and the attribute is marked as , map storage in JSON format.
/// 当实体类属性为【对象】时,并且标记特性 [JsonMap] 时,该属性将以JSON形式映射存储 ///
/// @@ -43,7 +43,7 @@ public static class FreeSqlJsonMapCoreExtensions }); } - that.Aop.ConfigEntityProperty += new EventHandler((s, e) => + that.Aop.ConfigEntityProperty += (s, e) => { var isJsonMap = e.Property.GetCustomAttributes(typeof(JsonMapAttribute), false).Any() || _dicJsonMapFluentApi.TryGetValue(e.EntityType, out var tryjmfu) && tryjmfu.ContainsKey(e.Property.Name); if (isJsonMap) @@ -61,7 +61,6 @@ public static class FreeSqlJsonMapCoreExtensions }); } } - }); + }; } -} - +} \ No newline at end of file From 907141a57debd77c4e440ab88720adf195dcb34a Mon Sep 17 00:00:00 2001 From: AlexLEWIS Date: Wed, 11 Aug 2021 14:06:09 +0800 Subject: [PATCH 08/19] Add English version of README.MD --- .../README.zh-CN.md | 25 +++++++++++++++++++ .../FreeSql.Extensions.JsonMap/readme.md | 6 +++-- 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 Extensions/FreeSql.Extensions.JsonMap/README.zh-CN.md diff --git a/Extensions/FreeSql.Extensions.JsonMap/README.zh-CN.md b/Extensions/FreeSql.Extensions.JsonMap/README.zh-CN.md new file mode 100644 index 00000000..8bd20d1d --- /dev/null +++ b/Extensions/FreeSql.Extensions.JsonMap/README.zh-CN.md @@ -0,0 +1,25 @@ +**中文** | [English](README.MD) + +FreeSql 扩展包,将值对象映射成 `typeof(string)`,安装扩展包: + +> dotnet add package FreeSql.Extensions.JsonMap + +```csharp +fsql.UseJsonMap(); //开启功能 + +class TestConfig +{ + public int clicks { get; set; } + public string title { get; set; } +} + +[Table(Name = "sysconfig")] +public class S_SysConfig +{ + [Column(IsPrimary = true)] + public string Name { get; set; } + + [JsonMap] + public T Config { get; set; } +} +``` \ No newline at end of file diff --git a/Extensions/FreeSql.Extensions.JsonMap/readme.md b/Extensions/FreeSql.Extensions.JsonMap/readme.md index 96906cd8..572deca2 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/readme.md +++ b/Extensions/FreeSql.Extensions.JsonMap/readme.md @@ -1,9 +1,11 @@ -FreeSql 扩展包,将值对象映射成 typeof(string),安装扩展包: +[中文](README.zh-CN.MD) | **English** + +FreeSql extension package, map *ValueObject* to `typeof(string)`, install the extension package: > dotnet add package FreeSql.Extensions.JsonMap ```csharp -fsql.UseJsonMap(); //开启功能 +fsql.UseJsonMap(); //Turn on function class TestConfig { From f302199e0ea623457c113054ed06e7a463767bd1 Mon Sep 17 00:00:00 2001 From: AlexLEWIS Date: Wed, 11 Aug 2021 14:06:13 +0800 Subject: [PATCH 09/19] Add English version of README.MD --- .../README.zh-CN.md | 128 ++++++++++++++++++ .../FreeSql.Extensions.BaseEntity/readme.md | 75 +++++----- 2 files changed, 167 insertions(+), 36 deletions(-) create mode 100644 Extensions/FreeSql.Extensions.BaseEntity/README.zh-CN.md diff --git a/Extensions/FreeSql.Extensions.BaseEntity/README.zh-CN.md b/Extensions/FreeSql.Extensions.BaseEntity/README.zh-CN.md new file mode 100644 index 00000000..4314961b --- /dev/null +++ b/Extensions/FreeSql.Extensions.BaseEntity/README.zh-CN.md @@ -0,0 +1,128 @@ +**中文** | [English](README.MD) + +# 前言 + +尝试过 ado.net、dapper、ef,以及Repository仓储,甚至自己还写过生成器工具,以便做常规CRUD操作。 + +它们日常操作不方便之处: + +- 每次使用前需要声明,再操作; + +- 很多人一个实体类,对应一个操作类(或DAL、DbContext、Repository); + +BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用; + +本文介绍 BaseEntity 一种极简约的 CRUD 操作方法。 + +# 功能特点 + +- 自动迁移实体结构(CodeFirst),到数据库; + +- 直接操作实体的方法,进行 CRUD 操作; + +- 简化用户定义实体类型,省去主键、常用字段的配置(如CreateTime、UpdateTime); + +- 实现单表、多表查询的软删除逻辑; + +# 声明 + +> dotnet add package FreeSql.Extensions.BaseEntity + +> dotnet add package FreeSql.Provider.Sqlite + +1、定义一个主键 int 并且自增的实体类型,BaseEntity TKey 指定为 int/long 时,会认为主键是自增; + +```csharp +public class UserGroup : BaseEntity +{ + public string GroupName { get; set; } +} +``` + +如果不想主键是自增键,可以重写属性: + +```csharp +public class UserGroup : BaseEntity +{ + [Column(IsIdentity = false)] + public override int Id { get; set; } + public string GroupName { get; set; } +} +``` +> 有关更多实体的特性配置,请参考资料:https://github.com/dotnetcore/FreeSql/wiki/%e5%ae%9e%e4%bd%93%e7%89%b9%e6%80%a7 + +2、定义一个主键 Guid 的实体类型,保存数据时会自动产生有序不重复的 Guid 值(不用自己指定 Guid.NewGuid()); + +```csharp +public class User : BaseEntity +{ + public string UserName { get; set; } +} +``` + +# CRUD 使用 + +```csharp +//添加 +var item = new UserGroup { GroupName = "组一" }; +item.Insert(); + +//更新 +item.GroupName = "组二"; +item.Update(); + +//添加或更新 +item.Save(); + +//软删除 +item.Delete(); + +//恢复软删除 +item.Restore(); + +//根据主键获取对象 +var item = UserGroup.Find(1); + +//查询数据 +var items = UserGroup.Where(a => a.Id > 10).ToList(); +``` + +实体类型.Select 是一个查询对象,使用方法和 FreeSql.ISelect 一样; + +支持多表查询时,软删除条件会附加在每个表中; + +> 有关更多查询方法,请参考资料:https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2 + +# 事务建议 + +由于 AsyncLocal 平台兼容不好,所以交给外部管理事务。 + +```csharp +static AsyncLocal _asyncUow = new AsyncLocal(); + +BaseEntity.Initialization(fsql, () => _asyncUow.Value); +``` + +在 Scoped 开始时: _asyncUow.Value = fsql.CreateUnitOfWork(); (也可以使用 UnitOfWorkManager 对象获取 uow) + +在 Scoped 结束时:_asyncUow.Value = null; + +如下: + +```csharp +using (var uow = fsql.CreateUnitOfWork()) +{ + _asyncUow.Value = uow; + + try + { + //todo ... BaseEntity 内部 curd 方法保持使用 uow 事务 + } + finally + { + _asyncUow.Value = null; + } + + uow.Commit(); +} +``` diff --git a/Extensions/FreeSql.Extensions.BaseEntity/readme.md b/Extensions/FreeSql.Extensions.BaseEntity/readme.md index bd1a0749..9f850945 100644 --- a/Extensions/FreeSql.Extensions.BaseEntity/readme.md +++ b/Extensions/FreeSql.Extensions.BaseEntity/readme.md @@ -1,34 +1,37 @@ -# 前言 +[中文](README.zh-CN.md) | **English** -尝试过 ado.net、dapper、ef,以及Repository仓储,甚至自己还写过生成器工具,以便做常规CRUD操作。 +# Preface -它们日常操作不方便之处: +I have tried ADO.NET, Dapper, EF, and Repository storage, and even wrote a generator tool myself to do common CRUD operations. -- 每次使用前需要声明,再操作; +Their operation is inconvenient: -- 很多人一个实体类,对应一个操作类(或DAL、DbContext、Repository); +- Need to declare before use; -BaseEntity 是一种极简单的 CodeFirst 开发方式,特别对单表或多表CRUD,利用继承节省了每个实体类的重复属性(创建时间、ID等字段),软件删除等功能,进行 crud 操作时不必时常考虑仓储的使用; +- Each entity class corresponds to an operation class (or DAL, DbContext, Repository). -本文介绍 BaseEntity 一种极简约的 CRUD 操作方法。 +BaseEntity is a very simple way of CodeFirst development, especially for single-table or multi-table CRUD operations. BaseEntity uses "inheritance" to save the repetitive code (creation time, ID and other fields) and functions of each entity class, and at the same time, it is not necessary to consider the use of repository when performing CURD operations. -# 功能特点 -- 自动迁移实体结构(CodeFirst),到数据库; +This article will introduce a very simple CRUD operation method of BaseEntity. -- 直接操作实体的方法,进行 CRUD 操作; +# Features -- 简化用户定义实体类型,省去主键、常用字段的配置(如CreateTime、UpdateTime); +- Automatically migrate the entity structure (CodeFirst) to the database; -- 实现单表、多表查询的软删除逻辑; +- Directly perform CRUD operations on entities; -# 声明 +- Simplify user-defined entity types, eliminating hard-coded primary keys, common fields and their configuration (such as CreateTime, UpdateTime); + +- Logic delete of single-table and multi-table query; + +# Declaring > dotnet add package FreeSql.Extensions.BaseEntity > dotnet add package FreeSql.Provider.Sqlite -1、定义一个主键 int 并且自增的实体类型,BaseEntity TKey 指定为 int/long 时,会认为主键是自增; +1. Define an auto-increment primary key of type `int`. When the `TKey` of `BaseEntity` is specified as `int/long`, the primary key will be considered as auto-increment; ```csharp public class UserGroup : BaseEntity @@ -37,7 +40,7 @@ public class UserGroup : BaseEntity } ``` -如果不想主键是自增键,可以重写属性: +If you don't want the primary key to be an auto-increment key, you can override the attribute: ```csharp public class UserGroup : BaseEntity @@ -47,9 +50,9 @@ public class UserGroup : BaseEntity public string GroupName { get; set; } } ``` -> 有关更多实体的特性配置,请参考资料:https://github.com/2881099/FreeSql/wiki/%e5%ae%9e%e4%bd%93%e7%89%b9%e6%80%a7 +> For more information about the attributes of entities, please refer to: https://github.com/dotnetcore/FreeSql/wiki/Entity-Attributes -2、定义一个主键 Guid 的实体类型,保存数据时会自动产生有序不重复的 Guid 值(不用自己指定 Guid.NewGuid()); +2. Define an entity whose primary key is Guid type, when saving data, it will automatically generate ordered and non-repeated Guid values (you don't need to specify `Guid.NewGuid()` yourself); ```csharp public class User : BaseEntity @@ -58,42 +61,42 @@ public class User : BaseEntity } ``` -# CRUD 使用 +# Usage of CRUD ```csharp -//添加 -var item = new UserGroup { GroupName = "组一" }; +//Insert Data +var item = new UserGroup { GroupName = "Group One" }; item.Insert(); -//更新 -item.GroupName = "组二"; +//Update Data +item.GroupName = "Group Two"; item.Update(); -//添加或更新 +//Insert or Update Data item.Save(); -//软删除 +//Logic Delete item.Delete(); -//恢复软删除 +//Recover Logic Delete item.Restore(); -//根据主键获取对象 +//Get the object by the primary key var item = UserGroup.Find(1); -//查询数据 +//Query Data var items = UserGroup.Where(a => a.Id > 10).ToList(); ``` -实体类型.Select 是一个查询对象,使用方法和 FreeSql.ISelect 一样; +`{ENTITY_TYPE}.Select` returns a query object, the same as `FreeSql.ISelect`. -支持多表查询时,软删除条件会附加在每个表中; +In the multi-table query, the logic delete condition will be attached to the query of each table. -> 有关更多查询方法,请参考资料:https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2 +> For more information about query data, please refer to: https://github.com/2881099/FreeSql/wiki/Query-Data -# 事务建议 +# Transaction Suggestion -由于 AsyncLocal 平台兼容不好,所以交给外部管理事务。 +Because the `AsyncLocal` platform is not compatible, the transaction is managed by the outside. ```csharp static AsyncLocal _asyncUow = new AsyncLocal(); @@ -101,11 +104,11 @@ static AsyncLocal _asyncUow = new AsyncLocal(); BaseEntity.Initialization(fsql, () => _asyncUow.Value); ``` -在 Scoped 开始时: _asyncUow.Value = fsql.CreateUnitOfWork(); (也可以使用 UnitOfWorkManager 对象获取 uow) +At the beginning of `Scoped`: `_asyncUow.Value = fsql.CreateUnitOfWork();` (You can also use the `UnitOfWorkManager` object to get uow) -在 Scoped 结束时:_asyncUow.Value = null; +At the end of `Scoped`: `_asyncUow.Value = null;` -如下: +as follows: ```csharp using (var uow = fsql.CreateUnitOfWork()) @@ -114,7 +117,7 @@ using (var uow = fsql.CreateUnitOfWork()) try { - //todo ... BaseEntity 内部 curd 方法保持使用 uow 事务 + //todo ... BaseEntity internal CURD method keeps using uow transaction } finally { From cc9182ee6c21c9cadfb730e9109accb2f68879c0 Mon Sep 17 00:00:00 2001 From: AlexLEWIS Date: Thu, 12 Aug 2021 00:10:25 +0800 Subject: [PATCH 10/19] Rename readme.md to README.MD --- Extensions/FreeSql.Extensions.BaseEntity/{readme.md => README.MD} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Extensions/FreeSql.Extensions.BaseEntity/{readme.md => README.MD} (100%) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/readme.md b/Extensions/FreeSql.Extensions.BaseEntity/README.MD similarity index 100% rename from Extensions/FreeSql.Extensions.BaseEntity/readme.md rename to Extensions/FreeSql.Extensions.BaseEntity/README.MD From 2fcdf84edb6179031504a552718807617bf41648 Mon Sep 17 00:00:00 2001 From: AlexLEWIS Date: Thu, 12 Aug 2021 00:12:31 +0800 Subject: [PATCH 11/19] Rename README.zh-CN.md to README.zh-CN.MD --- .../{README.zh-CN.md => README.zh-CN.MD} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Extensions/FreeSql.Extensions.BaseEntity/{README.zh-CN.md => README.zh-CN.MD} (100%) diff --git a/Extensions/FreeSql.Extensions.BaseEntity/README.zh-CN.md b/Extensions/FreeSql.Extensions.BaseEntity/README.zh-CN.MD similarity index 100% rename from Extensions/FreeSql.Extensions.BaseEntity/README.zh-CN.md rename to Extensions/FreeSql.Extensions.BaseEntity/README.zh-CN.MD From cca4aa08ea7f137126ed07e36484cdcc02ada6f1 Mon Sep 17 00:00:00 2001 From: AlexLEWIS Date: Thu, 12 Aug 2021 00:13:12 +0800 Subject: [PATCH 12/19] Rename README.zh-CN.md to README.zh-CN.MD --- .../{README.zh-CN.md => README.zh-CN.MD} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename Extensions/FreeSql.Extensions.JsonMap/{README.zh-CN.md => README.zh-CN.MD} (99%) diff --git a/Extensions/FreeSql.Extensions.JsonMap/README.zh-CN.md b/Extensions/FreeSql.Extensions.JsonMap/README.zh-CN.MD similarity index 99% rename from Extensions/FreeSql.Extensions.JsonMap/README.zh-CN.md rename to Extensions/FreeSql.Extensions.JsonMap/README.zh-CN.MD index 8bd20d1d..fa3f7c82 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/README.zh-CN.md +++ b/Extensions/FreeSql.Extensions.JsonMap/README.zh-CN.MD @@ -22,4 +22,4 @@ public class S_SysConfig [JsonMap] public T Config { get; set; } } -``` \ No newline at end of file +``` From 4c4ee1cda9373055c2826a960027fd4485d5bfe3 Mon Sep 17 00:00:00 2001 From: AlexLEWIS Date: Thu, 12 Aug 2021 00:13:34 +0800 Subject: [PATCH 13/19] Rename readme.md to README.MD --- Extensions/FreeSql.Extensions.JsonMap/{readme.md => README.MD} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename Extensions/FreeSql.Extensions.JsonMap/{readme.md => README.MD} (99%) diff --git a/Extensions/FreeSql.Extensions.JsonMap/readme.md b/Extensions/FreeSql.Extensions.JsonMap/README.MD similarity index 99% rename from Extensions/FreeSql.Extensions.JsonMap/readme.md rename to Extensions/FreeSql.Extensions.JsonMap/README.MD index 572deca2..92e9f6fc 100644 --- a/Extensions/FreeSql.Extensions.JsonMap/readme.md +++ b/Extensions/FreeSql.Extensions.JsonMap/README.MD @@ -22,4 +22,4 @@ public class S_SysConfig [JsonMap] public T Config { get; set; } } -``` \ No newline at end of file +``` From c43602f3a75421075e38397d56a757176e0d4186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=91=A3=E6=94=BE?= Date: Sat, 14 Aug 2021 02:18:15 +0800 Subject: [PATCH 14/19] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=94=9F=E6=88=90?= =?UTF-8?q?=E5=99=A8=E5=B0=86=E6=95=B0=E6=8D=AE=E5=BA=93=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=80=BC=E5=86=99=E5=85=A5=E7=94=9F=E6=88=90cs=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E6=97=B6=EF=BC=8C=E5=B0=86=E9=BB=98=E8=AE=A4=E5=80=BC?= =?UTF-8?q?=E5=8F=98=E4=B8=BA=E8=BD=AC=E4=B9=89=E5=AD=97=E7=AC=A6=E5=86=99?= =?UTF-8?q?=E5=85=A5=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FreeSql.Generator.csproj | 1 + Extensions/FreeSql.Generator/RazorModel.cs | 23 +++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj index d63429eb..02579dbf 100644 --- a/Extensions/FreeSql.Generator/FreeSql.Generator.csproj +++ b/Extensions/FreeSql.Generator/FreeSql.Generator.csproj @@ -19,6 +19,7 @@ + diff --git a/Extensions/FreeSql.Generator/RazorModel.cs b/Extensions/FreeSql.Generator/RazorModel.cs index 326724de..7f181fd7 100644 --- a/Extensions/FreeSql.Generator/RazorModel.cs +++ b/Extensions/FreeSql.Generator/RazorModel.cs @@ -4,7 +4,10 @@ using FreeSql.DatabaseModel; using FreeSql.Internal.CommonProvider; using MySqlConnector; using System; +using System.CodeDom; +using System.CodeDom.Compiler; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; @@ -50,7 +53,17 @@ public class RazorModel if (text.Length <= 1) return text.ToLower(); else return text.Substring(0, 1).ToLower() + text.Substring(1, text.Length - 1); } - + private string LiteralString(string text) + { + using (var writer = new StringWriter()) + { + using (var provider = CodeDomProvider.CreateProvider("CSharp")) + { + provider.GenerateCodeFromExpression(new CodePrimitiveExpression(text), writer, null); + return writer.ToString(); + } + } + } public string GetCsType(DbColumnInfo col) { if (fsql.Ado.DataType == FreeSql.DataType.MySql) @@ -250,10 +263,10 @@ public class RazorModel if (cstype == typeof(decimal)) return defval + "M"; return defval; } - if (cstype == typeof(Guid) && Guid.TryParse(defval, out var tryguid)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"Guid.Parse(\"{defval.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")}\")"; - if (cstype == typeof(DateTime) && DateTime.TryParse(defval, out var trydt)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"DateTime.Parse(\"{defval.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")}\")"; - if (cstype == typeof(TimeSpan) && TimeSpan.TryParse(defval, out var tryts)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"TimeSpan.Parse(\"{defval.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")}\")"; - if (cstype == typeof(string)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"@\"{defval.Replace("\r\n", "\\r\\n").Replace("\"", "\\\"")}\""; + if (cstype == typeof(Guid) && Guid.TryParse(defval, out var tryguid)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"Guid.Parse({LiteralString(defval)})"; + if (cstype == typeof(DateTime) && DateTime.TryParse(defval, out var trydt)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"DateTime.Parse({LiteralString(defval)})"; + if (cstype == typeof(TimeSpan) && TimeSpan.TryParse(defval, out var tryts)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : $"TimeSpan.Parse({LiteralString(defval)})"; + if (cstype == typeof(string)) return isInsertValueSql ? (fsql.Select() as Select0Provider)._commonUtils.FormatSql("{0}", defval) : LiteralString(defval); if (cstype == typeof(bool)) return isInsertValueSql ? defval : (defval == "1" || defval == "t" ? "true" : "false"); if (fsql.Ado.DataType == DataType.MySql || fsql.Ado.DataType == DataType.OdbcMySql) if (col.DbType == (int)MySqlDbType.Enum || col.DbType == (int)MySqlDbType.Set) From 6108b73672cd768241439b1f7492315a66ff3cd7 Mon Sep 17 00:00:00 2001 From: AlexLEWIS Date: Tue, 17 Aug 2021 22:49:38 +0800 Subject: [PATCH 15/19] Update README.md --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 23acdc3a..17929616 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ FreeSql is a powerful O/RM component, supports .NET Core 2.1+, .NET Framework 4. [![Member project of .NET Core Community](https://img.shields.io/badge/member%20project%20of-NCC-9e20c9.svg)](https://github.com/dotnetcore) [![nuget](https://img.shields.io/nuget/v/FreeSql.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql) [![stats](https://img.shields.io/nuget/dt/FreeSql.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql?groupby=Version) -[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/2881099/FreeSql/master/LICENSE.txt) +[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/dotnetcore/FreeSql/master/LICENSE.txt)

English | @@ -15,30 +15,30 @@ FreeSql is a powerful O/RM component, supports .NET Core 2.1+, .NET Framework 4. - 🛠 Support CodeFirst data migration. -- 💻 Support DbFirst import entity class from database, or use [Generation Tool](https://github.com/2881099/FreeSql/wiki/DbFirst). +- 💻 Support DbFirst import entity class from database, or use [Generation Tool](https://github.com/dotnetcore/FreeSql/wiki/DbFirst). - ⛳ Support advanced type mapping, such as PostgreSQL array type, etc. - 🌲 Support expression functions, and customizable analysis. - 🏁 Support one-to-many and many-to-many navigation properties, include and lazy loading. - 📃 Support Read/Write separation, Splitting Table/Database, Global filters, Optimistic and pessimistic locker. -- 🌳 Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/神舟通用/翰高/华为GaussDB/Access, etc. +- 🌳 Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/Dameng/人大金仓/Shentong Database/翰高/HUAWEI GaussDB/Access, etc. -QQ Groups:4336577(full)、**8578575(full)**、**52508226(available)** +QQ Groups:4336577(full)、8578575(full)、**52508226(available)** ## 📚 Documentation | | | - | -| [Get started](https://www.cnblogs.com/FreeSql/p/11531300.html)  \|  [Select](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2)  \|  [Update](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9)  \|  [Insert](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0)  \|  [Delete](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4)  \|  [FAQ](https://github.com/dotnetcore/FreeSql/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98)  | -| [Expression](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0)  \|  [CodeFirst](https://github.com/2881099/FreeSql/wiki/CodeFirst)  \|  [DbFirst](https://github.com/2881099/FreeSql/wiki/DbFirst)  \|  [Filters](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8)  \|  [AOP](https://github.com/2881099/FreeSql/wiki/AOP)  | -| [Repository](https://github.com/2881099/FreeSql/wiki/Repository)  \|  [UnitOfWork](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83)  \|  [DbContext](https://github.com/2881099/FreeSql/wiki/DbContext)  \|  [ADO](https://github.com/2881099/FreeSql/wiki/ADO)  | -| [Read/Write](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb)  \|  [Splitting Table](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e8%a1%a8%e5%88%86%e5%ba%93)  \|  [Hide tech](https://github.com/2881099/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C)  \|  [*Update Notes*](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97)  | +| [Get started](https://www.cnblogs.com/FreeSql/p/11531300.html)  \|  [Select](https://github.com/dotnetcore/FreeSql/wiki/%e6%9f%a5%e8%af%a2)  \|  [Update](https://github.com/dotnetcore/FreeSql/wiki/Update-Data)  \|  [Insert](https://github.com/dotnetcore/FreeSql/wiki/Insert-Data)  \|  [Delete](https://github.com/dotnetcore/FreeSql/wiki/Delete-Data)  \|  [FAQ](https://github.com/dotnetcore/FreeSql/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98)  | +| [Expression](https://github.com/dotnetcore/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0)  \|  [CodeFirst](https://github.com/dotnetcore/FreeSql/wiki/CodeFirst)  \|  [DbFirst](https://github.com/2881099/FreeSql/wiki/DbFirst)  \|  [Filters](https://github.com/dotnetcore/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8)  \|  [AOP](https://github.com/2881099/FreeSql/wiki/AOP)  | +| [Repository](https://github.com/dotnetcore/FreeSql/wiki/Repository)  \|  [UnitOfWork](https://github.com/dotnetcore/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83)  \|  [DbContext](https://github.com/dotnetcore/FreeSql/wiki/DbContext)  \|  [ADO](https://github.com/2881099/FreeSql/wiki/ADO)  | +| [Read/Write](https://github.com/dotnetcore/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb)  \|  [Splitting Table](https://github.com/dotnetcore/FreeSql/wiki/%e5%88%86%e8%a1%a8%e5%88%86%e5%ba%93)  \|  [Hide tech](https://github.com/dotnetcore/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C)  \|  [*Update Notes*](https://github.com/dotnetcore/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97)  | > Please select a development mode: - Use FreeSql, keep the original usage. -- Use [FreeSql.Repository](https://github.com/2881099/FreeSql/wiki/Repository), Repository + UnitOfWork. -- Use [FreeSql.DbContext](https://github.com/2881099/FreeSql/wiki/DbContext), Like efcore. -- Use [FreeSql.BaseEntity](https://github.com/2881099/FreeSql/tree/master/Examples/base_entity), Simple mode. +- Use [FreeSql.Repository](https://github.com/dotnetcore/FreeSql/wiki/Repository), Repository + UnitOfWork. +- Use [FreeSql.DbContext](https://github.com/dotnetcore/FreeSql/wiki/DbContext), Like efcore. +- Use [FreeSql.BaseEntity](https://github.com/dotnetcore/FreeSql/tree/master/Examples/base_entity), Simple mode. > Some open source projects that use FreeSql: @@ -113,7 +113,7 @@ fsql.Select() .OrderByDescending(a => a.Id) .ToList() ``` -[More..](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) +[More..](https://github.com/dotnetcore/FreeSql/wiki/%e6%9f%a5%e8%af%a2) ```csharp fsql.Select().Where(a => new[] { 1, 2, 3 }.Contains(a.Id)).ToList(); @@ -122,7 +122,7 @@ fsql.Select().Where(a => a.CreateTime.Date == DateTime.Today).ToList(); fsql.Select().OrderBy(a => Guid.NewGuid()).Limit(10).ToList(); ``` -[More..](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) +[More..](https://github.com/dotnetcore/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) ### 🚁 Repository @@ -175,7 +175,7 @@ Elapsed: 00:00:00.6707125; ToList Entity Counts: 131072; ORM: FreeSql* Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper ``` -[More..](https://github.com/2881099/FreeSql/wiki/%e6%80%a7%e8%83%bd) +[More..](https://github.com/dotnetcore/FreeSql/wiki/%e6%80%a7%e8%83%bd) ## 👯 Contributors From 212dfbbaed46dba4ceba12945e83ab7158917f0a Mon Sep 17 00:00:00 2001 From: Zero look <33046233+wch1618@users.noreply.github.com> Date: Thu, 19 Aug 2021 11:39:00 +0800 Subject: [PATCH 16/19] =?UTF-8?q?=E5=8E=9F=E6=84=8F=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E6=98=AF=E4=BD=BF=E7=94=A8IsGenericTypeDefinition=E5=8D=B4?= =?UTF-8?q?=E7=94=A8=E4=BA=86IsGenericType?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSqlBuilder.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 2a15d347..6c8be1d6 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -171,10 +171,14 @@ namespace FreeSql if (string.IsNullOrEmpty(_masterConnectionString) && _connectionFactory == null) throw new Exception("参数 masterConnectionString 不可为空,请检查 UseConnectionString"); IFreeSql ret = null; var type = _providerType; - if (type?.IsGenericType == true) type = type.MakeGenericType(typeof(TMark)); - if (type == null) + if (type != null) { - Action throwNotFind = (dll, providerType) => throw new Exception($"缺少 FreeSql 数据库实现包:{dll},可前往 nuget 下载;如果存在 {dll} 依然报错(原因是环境问题导致反射不到类型),请在 UseConnectionString/UseConnectionFactory 第三个参数手工传入 typeof({providerType})"); + if (type.IsGenericTypeDefinition) + type = type.MakeGenericType(typeof(TMark)); + } + else + { + Action throwNotFind = (dll, providerType) => throw new Exception($"缺少 FreeSql 数据库实现包:{dll},可前往 nuget 下载;如果存在 {dll} 依然报错(原因是环境问题导致反射不到类型),请在 UseConnectionString/UseConnectionFactory 第三个参数手工传入 typeof({providerType})"); switch (_dataType) { case DataType.MySql: From 74149c51dd27ec845ce9aa0afa37a83f46a5bf9a Mon Sep 17 00:00:00 2001 From: Zero look <33046233+wch1618@users.noreply.github.com> Date: Thu, 19 Aug 2021 11:43:06 +0800 Subject: [PATCH 17/19] --- FreeSql/FreeSqlBuilder.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 6c8be1d6..892ab719 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -173,12 +173,12 @@ namespace FreeSql var type = _providerType; if (type != null) { - if (type.IsGenericTypeDefinition) - type = type.MakeGenericType(typeof(TMark)); - } - else + if (type.IsGenericTypeDefinition) + type = type.MakeGenericType(typeof(TMark)); + } + else { - Action throwNotFind = (dll, providerType) => throw new Exception($"缺少 FreeSql 数据库实现包:{dll},可前往 nuget 下载;如果存在 {dll} 依然报错(原因是环境问题导致反射不到类型),请在 UseConnectionString/UseConnectionFactory 第三个参数手工传入 typeof({providerType})"); + Action throwNotFind = (dll, providerType) => throw new Exception($"缺少 FreeSql 数据库实现包:{dll},可前往 nuget 下载;如果存在 {dll} 依然报错(原因是环境问题导致反射不到类型),请在 UseConnectionString/UseConnectionFactory 第三个参数手工传入 typeof({providerType})"); switch (_dataType) { case DataType.MySql: From 35a332c126f404030799cbc157dfcf00872897d3 Mon Sep 17 00:00:00 2001 From: Zero look <33046233+wch1618@users.noreply.github.com> Date: Thu, 19 Aug 2021 11:45:05 +0800 Subject: [PATCH 18/19] --- FreeSql/FreeSqlBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 892ab719..344e2a2c 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -177,7 +177,7 @@ namespace FreeSql type = type.MakeGenericType(typeof(TMark)); } else - { + { Action throwNotFind = (dll, providerType) => throw new Exception($"缺少 FreeSql 数据库实现包:{dll},可前往 nuget 下载;如果存在 {dll} 依然报错(原因是环境问题导致反射不到类型),请在 UseConnectionString/UseConnectionFactory 第三个参数手工传入 typeof({providerType})"); switch (_dataType) { From f7ea080d47f9ed66bf97f40347bad1f068592dca Mon Sep 17 00:00:00 2001 From: AlexLEWIS Date: Fri, 20 Aug 2021 13:51:40 +0800 Subject: [PATCH 19/19] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 17929616..b46082c1 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ QQ Groups:4336577(full)、8578575(full)、**52508226(available)** | | | - | -| [Get started](https://www.cnblogs.com/FreeSql/p/11531300.html)  \|  [Select](https://github.com/dotnetcore/FreeSql/wiki/%e6%9f%a5%e8%af%a2)  \|  [Update](https://github.com/dotnetcore/FreeSql/wiki/Update-Data)  \|  [Insert](https://github.com/dotnetcore/FreeSql/wiki/Insert-Data)  \|  [Delete](https://github.com/dotnetcore/FreeSql/wiki/Delete-Data)  \|  [FAQ](https://github.com/dotnetcore/FreeSql/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98)  | +| [Get started](https://www.cnblogs.com/FreeSql/p/11531300.html)  \|  [Select](https://github.com/dotnetcore/FreeSql/wiki/Query-Data)  \|  [Update](https://github.com/dotnetcore/FreeSql/wiki/Update-Data)  \|  [Insert](https://github.com/dotnetcore/FreeSql/wiki/Insert-Data)  \|  [Delete](https://github.com/dotnetcore/FreeSql/wiki/Delete-Data)  \|  [FAQ](https://github.com/dotnetcore/FreeSql/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98)  | | [Expression](https://github.com/dotnetcore/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0)  \|  [CodeFirst](https://github.com/dotnetcore/FreeSql/wiki/CodeFirst)  \|  [DbFirst](https://github.com/2881099/FreeSql/wiki/DbFirst)  \|  [Filters](https://github.com/dotnetcore/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8)  \|  [AOP](https://github.com/2881099/FreeSql/wiki/AOP)  | | [Repository](https://github.com/dotnetcore/FreeSql/wiki/Repository)  \|  [UnitOfWork](https://github.com/dotnetcore/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83)  \|  [DbContext](https://github.com/dotnetcore/FreeSql/wiki/DbContext)  \|  [ADO](https://github.com/2881099/FreeSql/wiki/ADO)  | | [Read/Write](https://github.com/dotnetcore/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb)  \|  [Splitting Table](https://github.com/dotnetcore/FreeSql/wiki/%e5%88%86%e8%a1%a8%e5%88%86%e5%ba%93)  \|  [Hide tech](https://github.com/dotnetcore/FreeSql/wiki/%E9%AA%9A%E6%93%8D%E4%BD%9C)  \|  [*Update Notes*](https://github.com/dotnetcore/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97)  |