diff --git a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj index 3a490ea7..80f24053 100644 --- a/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj +++ b/Extensions/FreeSql.Extensions.LazyLoading/FreeSql.Extensions.LazyLoading.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.9 + 0.6.10 true YeXiangQin FreeSql 扩展包,可实现【延时加载】属性. diff --git a/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs b/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs index d373da3f..815821ec 100644 --- a/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs +++ b/FreeSql.Tests/DataAnnotations/MySqlFluentTest.cs @@ -1,4 +1,5 @@ using FreeSql.DataAnnotations; +using MySql.Data.MySqlClient; using System; using System.Linq; using Xunit; @@ -9,6 +10,22 @@ namespace FreeSql.Tests.DataAnnotations { public MySqlFluentTest() { } + [Fact] + public void DisableSyncStructure() { + Assert.Throws(() => g.mysql.Select().ToList()); + + g.mysql.Select().ToList(); + } + [Table(DisableSyncStructure = true)] + class ModelDisableSyncStructure { + [Column(IsPrimary = false)] + public int pkid { get; set; } + } + class ModelSyncStructure { + [Column(IsPrimary = false)] + public int pkid { get; set; } + } + [Fact] public void AopConfigEntity() { g.mysql.CodeFirst.ConfigEntity(a => a.Property(b => b.pkid).IsPrimary(true)); diff --git a/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs b/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs index c178dcb7..f4354f51 100644 --- a/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs +++ b/FreeSql.Tests/DataAnnotations/SqlServerFluentTest.cs @@ -1,6 +1,7 @@ using FreeSql.DataAnnotations; using FreeSql.Tests.DataContext.SqlServer; using System; +using System.Data.SqlClient; using Xunit; namespace FreeSql.Tests.DataAnnotations { @@ -14,6 +15,22 @@ namespace FreeSql.Tests.DataAnnotations { _sqlserverFixture = sqlserverFixture; } + [Fact] + public void DisableSyncStructure() { + Assert.Throws(() => _sqlserverFixture.SqlServer.Select().ToList()); + + _sqlserverFixture.SqlServer.Select().ToList(); + } + [Table(DisableSyncStructure = true)] + class ModelDisableSyncStructure { + [Column(IsPrimary = false)] + public int pkid { get; set; } + } + class ModelSyncStructure { + [Column(IsPrimary = false)] + public int pkid { get; set; } + } + [Fact] public void Fluent() { _sqlserverFixture.SqlServer.CodeFirst diff --git a/FreeSql/DataAnnotations/TableAttribute.cs b/FreeSql/DataAnnotations/TableAttribute.cs index fe6788a5..c1061e93 100644 --- a/FreeSql/DataAnnotations/TableAttribute.cs +++ b/FreeSql/DataAnnotations/TableAttribute.cs @@ -17,6 +17,12 @@ namespace FreeSql.DataAnnotations { /// public string SelectFilter { get; set; } + internal bool? _DisableSyncStructure; + /// + /// 禁用 CodeFirst 同步结构迁移 + /// + public bool DisableSyncStructure { get => _DisableSyncStructure ?? false; set => _DisableSyncStructure = value; } + internal ConcurrentDictionary _columns { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); } } diff --git a/FreeSql/DataAnnotations/TableFluent.cs b/FreeSql/DataAnnotations/TableFluent.cs index 781a812b..64383cd4 100644 --- a/FreeSql/DataAnnotations/TableFluent.cs +++ b/FreeSql/DataAnnotations/TableFluent.cs @@ -38,6 +38,14 @@ namespace FreeSql.DataAnnotations { return this; } + /// + /// 禁用 CodeFirst 同步结构迁移 + /// + public TableFluent DisableSyncStructure(bool value) { + _table.DisableSyncStructure = value; + return this; + } + public ColumnFluent Property(string proto) { if (_properties.ContainsKey(proto) == false) throw new KeyNotFoundException($"找不到属性名 {proto}"); var col = _table._columns.GetOrAdd(proto, name => new ColumnAttribute { Name = proto }); @@ -74,6 +82,14 @@ namespace FreeSql.DataAnnotations { return this; } + /// + /// 禁用 CodeFirst 同步结构迁移 + /// + public TableFluent DisableSyncStructure(bool value) { + _table.DisableSyncStructure = value; + return this; + } + public ColumnFluent Property(Expression> column) { var proto = (column.Body as MemberExpression)?.Member; if (proto == null) throw new FormatException($"错误的表达式格式 {column}"); diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 499c1ef9..cd3eb7be 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.9 + 0.6.10 true YeXiangQin FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite. diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 40fae6b3..77e52249 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -133,6 +133,11 @@ 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 + + + 禁用 CodeFirst 同步结构迁移 + + 数据库表名 @@ -148,6 +153,11 @@ 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 + + + 禁用 CodeFirst 同步结构迁移 + + 数据库表名 @@ -163,6 +173,11 @@ 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 + + + 禁用 CodeFirst 同步结构迁移 + + 所属表 @@ -480,6 +495,15 @@ 执行后,可监视执行性能 + + + 自动转换实体属性名称 Entity Property -> Db Filed + + *不会覆盖 [Column] 特性设置的Name + + + + 指定事务对象 @@ -2251,6 +2275,55 @@ 中间表,多对多 + + + 不进行任何处理 + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 + + BigApple -> BIG_APPLE + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写 + + BigApple -> big_apple + + + + + 将字符串转换为大写 + + BigApple -> BIGAPPLE + + + + + 将字符串转换为小写 + + BigApple -> bigapple + + + + + 将帕斯卡命名字符串转换为下划线分隔字符串 + + BigApple -> Big_Apple + + + + 测量两个经纬度的距离,返回单位:米 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index 6574371e..56fca2a8 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -147,7 +147,7 @@ namespace FreeSql { ret = Activator.CreateInstance(type, new object[] { _masterConnectionString, _slaveConnectionString }) as IFreeSql; if (ret != null) { ret.CodeFirst.IsAutoSyncStructure = _isAutoSyncStructure; - + ret.CodeFirst.IsSyncStructureToLower = _isSyncStructureToLower; ret.CodeFirst.IsSyncStructureToUpper = _isSyncStructureToUpper; ret.CodeFirst.IsConfigEntityFromDbFirst = _isConfigEntityFromDbFirst; @@ -157,73 +157,39 @@ namespace FreeSql { ado.AopCommandExecuting += _aopCommandExecuting; ado.AopCommandExecuted += _aopCommandExecuted; - //添加实体属性名全局AOP转换处理 - if (_entityPropertyConvertType != StringConvertType.None) - { - // 局部方法判断是否存在Column特性以及是否设置Name的值 - bool CheckEntityPropertyColumnAttribute(PropertyInfo propertyInfo) - { - var attr = propertyInfo.GetCustomAttribute(); - if (attr == null || string.IsNullOrEmpty(attr.Name)) - { - return true; - } - - return false; - } - - switch (_entityPropertyConvertType) - { - case StringConvertType.Lower: - ret.Aop.ConfigEntityProperty = (s, e) => - { - if (CheckEntityPropertyColumnAttribute(e.Property)) - { - e.ModifyResult.Name = e.Property.Name.ToLower(); - } - }; - break; - case StringConvertType.Upper: - ret.Aop.ConfigEntityProperty = (s, e) => - { - if (CheckEntityPropertyColumnAttribute(e.Property)) - { - e.ModifyResult.Name = e.Property.Name.ToUpper(); - } - }; - break; - case StringConvertType.PascalCaseToUnderscore: - ret.Aop.ConfigEntityProperty = (s, e) => - { - if (CheckEntityPropertyColumnAttribute(e.Property)) - { - e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name); - } - }; - break; - case StringConvertType.PascalCaseToUnderscoreWithLower: - ret.Aop.ConfigEntityProperty = (s, e) => - { - if (CheckEntityPropertyColumnAttribute(e.Property)) - { - e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToLower(); - } - }; - break; - case StringConvertType.PascalCaseToUnderscoreWithUpper: - ret.Aop.ConfigEntityProperty = (s, e) => - { - if (CheckEntityPropertyColumnAttribute(e.Property)) - { - e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToUpper(); - } - }; - break; - default: - break; - } - } - } + //添加实体属性名全局AOP转换处理 + if (_entityPropertyConvertType != StringConvertType.None) { + switch (_entityPropertyConvertType) { + case StringConvertType.Lower: + ret.Aop.ConfigEntityProperty = (s, e) => { + e.ModifyResult.Name = e.Property.Name.ToLower(); + }; + break; + case StringConvertType.Upper: + ret.Aop.ConfigEntityProperty = (s, e) => { + e.ModifyResult.Name = e.Property.Name.ToUpper(); + }; + break; + case StringConvertType.PascalCaseToUnderscore: + ret.Aop.ConfigEntityProperty = (s, e) => { + e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name); + }; + break; + case StringConvertType.PascalCaseToUnderscoreWithLower: + ret.Aop.ConfigEntityProperty = (s, e) => { + e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToLower(); + }; + break; + case StringConvertType.PascalCaseToUnderscoreWithUpper: + ret.Aop.ConfigEntityProperty = (s, e) => { + e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToUpper(); + }; + break; + default: + break; + } + } + } return ret; } diff --git a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs index 5a12ce5b..6f611883 100644 --- a/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs +++ b/FreeSql/Internal/CommonProvider/CodeFirstProvider.cs @@ -45,9 +45,9 @@ namespace FreeSql.Internal.CommonProvider { internal ConcurrentDictionary dicSyced = new ConcurrentDictionary(); public bool SyncStructure() => this.SyncStructure(typeof(TEntity)); public bool SyncStructure(params Type[] entityTypes) { - if (entityTypes == null) return true; - var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a.FullName) == false).ToArray(); - if (syncTypes.Any() == false) return true; + if (entityTypes == null) return false; + var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a.FullName) == false && GetTableByEntity(a)?.DisableSyncStructure == false).ToArray(); + if (syncTypes.Any() == false) return false; var before = new Aop.SyncStructureBeforeEventArgs(entityTypes); _orm.Aop.SyncStructureBefore?.Invoke(this, before); Exception exception = null; diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 3c23e48d..c2510bf5 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -73,6 +73,8 @@ namespace FreeSql.Internal { if (!string.IsNullOrEmpty(trytb.Name)) attr.Name = trytb.Name; if (!string.IsNullOrEmpty(trytb.OldName)) attr.OldName = trytb.OldName; if (!string.IsNullOrEmpty(trytb.SelectFilter)) attr.SelectFilter = trytb.SelectFilter; + if (trytb._DisableSyncStructure != null) attr._DisableSyncStructure = trytb.DisableSyncStructure; + } var attrs = type.GetCustomAttributes(typeof(TableAttribute), false); foreach (var tryattrobj in attrs) { @@ -81,10 +83,12 @@ namespace FreeSql.Internal { if (!string.IsNullOrEmpty(tryattr.Name)) attr.Name = tryattr.Name; if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName; if (!string.IsNullOrEmpty(tryattr.SelectFilter)) attr.SelectFilter = tryattr.SelectFilter; + if (tryattr._DisableSyncStructure != null) attr._DisableSyncStructure = tryattr.DisableSyncStructure; } if (!string.IsNullOrEmpty(attr.Name)) return attr; if (!string.IsNullOrEmpty(attr.OldName)) return attr; if (!string.IsNullOrEmpty(attr.SelectFilter)) return attr; + if (attr._DisableSyncStructure != null) return attr; return null; } public ColumnAttribute GetEntityColumnAttribute(Type type, PropertyInfo proto) { diff --git a/FreeSql/Internal/Model/TableInfo.cs b/FreeSql/Internal/Model/TableInfo.cs index adaa0678..c08cfdb7 100644 --- a/FreeSql/Internal/Model/TableInfo.cs +++ b/FreeSql/Internal/Model/TableInfo.cs @@ -18,6 +18,7 @@ namespace FreeSql.Internal.Model { public string DbName { get; set; } public string DbOldName { get; set; } public string SelectFilter { get; set; } + public bool DisableSyncStructure { get; set; } public ColumnInfo VersionColumn { get; set; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index b81b7c1b..1b38ca9f 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -53,6 +53,7 @@ namespace FreeSql.Internal { trytb.DbOldName = trytb.DbOldName?.ToUpper(); } trytb.SelectFilter = tbattr?.SelectFilter; + if (tbattr != null) trytb.DisableSyncStructure = tbattr.DisableSyncStructure; var propsLazy = new List<(PropertyInfo, bool, bool)>(); var propsNavObjs = new List(); foreach (var p in trytb.Properties.Values) { diff --git a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj index 93c45632..348ebb56 100644 --- a/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj +++ b/Providers/FreeSql.Provider.MySql/FreeSql.Provider.MySql.csproj @@ -2,7 +2,7 @@ netstandard2.0;net452 - 0.6.9 + 0.6.10 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj index 5e1ce63f..667ae1e4 100644 --- a/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj +++ b/Providers/FreeSql.Provider.MySqlConnector/FreeSql.Provider.MySqlConnector.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.9 + 0.6.10 true YeXiangQin FreeSql 数据库实现,基于 MySql 5.6 diff --git a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj index b53610f6..9b5064d8 100644 --- a/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj +++ b/Providers/FreeSql.Provider.Oracle/FreeSql.Provider.Oracle.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.9 + 0.6.10 true YeXiangQin FreeSql 数据库实现,基于 Oracle 11 diff --git a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj index 896c9f4f..e2ff1e19 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj +++ b/Providers/FreeSql.Provider.PostgreSQL/FreeSql.Provider.PostgreSQL.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.9 + 0.6.10 true YeXiangQin FreeSql 数据库实现,基于 PostgreSQL 9.5 diff --git a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj index fc9e1384..0546a070 100644 --- a/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj +++ b/Providers/FreeSql.Provider.SqlServer/FreeSql.Provider.SqlServer.csproj @@ -2,7 +2,7 @@ netstandard2.0;net451 - 0.6.9 + 0.6.10 true YeXiangQin FreeSql 数据库实现,基于 SqlServer 2005+,并根据版本适配分页方法:row_number 或 offset fetch next diff --git a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj index 5e3e0aaa..a53f4f70 100644 --- a/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj +++ b/Providers/FreeSql.Provider.Sqlite/FreeSql.Provider.Sqlite.csproj @@ -2,7 +2,7 @@ netstandard2.0;net45 - 0.6.9 + 0.6.10 true YeXiangQin FreeSql 数据库实现,基于 Sqlite 3.0