From 72c3d91ca1efab5c8b0c765784f24333550841ef Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Tue, 31 Mar 2020 12:42:13 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20CodeFirst=20=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E7=B1=BB=E6=B3=A8=E9=87=8A=20->=20=E8=A1=A8=E5=A4=87?= =?UTF-8?q?=E6=B3=A8=EF=BC=8C=E4=B9=8B=E5=89=8D=E5=8F=AA=E8=83=BD=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E6=B3=A8=E9=87=8A=20->=20=E5=AD=97=E6=AE=B5=E5=A4=87?= =?UTF-8?q?=E6=B3=A8=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 26 +++- Examples/base_entity/Test01/User.cs | 4 +- Examples/base_entity/Test01/UserRole.cs | 4 +- Examples/base_entity/base_entity.csproj | 1 + Examples/base_entity/base_entity.xml | 6 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 -- FreeSql/FreeSql.xml | 143 ------------------ FreeSql/FreeSqlBuilder.cs | 2 + FreeSql/Internal/CommonUtils.cs | 12 +- FreeSql/Internal/Model/TableInfo.cs | 1 + FreeSql/Internal/UtilsExpressionTree.cs | 10 +- .../FreeSql.Provider.MySql/MySqlCodeFirst.cs | 15 +- .../Dameng/OdbcDamengCodeFirst.cs | 23 ++- .../MySql/OdbcMySqlCodeFirst.cs | 15 +- .../Oracle/OdbcOracleCodeFirst.cs | 26 +++- .../PostgreSQL/OdbcPostgreSQLCodeFirst.cs | 19 ++- .../PostgreSQL/OdbcPostgreSQLDbFirst.cs | 2 +- .../SqlServer/OdbcSqlServerCodeFirst.cs | 38 +++++ .../OracleCodeFirst.cs | 20 ++- .../PostgreSQLCodeFirst.cs | 19 ++- .../PostgreSQLDbFirst.cs | 2 +- .../SqlServerCodeFirst.cs | 38 +++++ 22 files changed, 253 insertions(+), 182 deletions(-) diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 5cb92a98..97aad3ee 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -41,15 +41,39 @@ namespace base_entity var fsql = new FreeSql.FreeSqlBuilder() .UseAutoSyncStructure(true) .UseNoneCommandParameter(true) + .UseConnectionString(FreeSql.DataType.Sqlite, "data source=test.db;max pool size=5") + //.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=2") - .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") + + //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3") + + //.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") + //.UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + + + //.UseConnectionString(FreeSql.DataType.OdbcMySql, "Driver={MySQL ODBC 8.0 Unicode Driver};Server=127.0.0.1;Persist Security Info=False;Trusted_Connection=Yes;UID=root;PWD=root;DATABASE=cccddd_odbc;Charset=utf8;SslMode=none;Max pool size=2") + + //.UseConnectionString(FreeSql.DataType.OdbcSqlServer, "Driver={SQL Server};Server=.;Persist Security Info=False;Trusted_Connection=Yes;Integrated Security=True;DATABASE=freesqlTest_odbc;Pooling=true;Max pool size=3") + + //.UseConnectionString(FreeSql.DataType.OdbcPostgreSQL, "Driver={PostgreSQL Unicode(x64)};Server=192.168.164.10;Port=5432;UID=postgres;PWD=123456;Database=tedb_odbc;Pooling=true;Maximum Pool Size=2") + //.UseNameConvert(FreeSql.Internal.NameConvertType.ToLower) + + //.UseConnectionString(FreeSql.DataType.OdbcOracle, "Driver={Oracle in XE};Server=//127.0.0.1:1521/XE;Persist Security Info=False;Trusted_Connection=Yes;UID=odbc1;PWD=123456") + //.UseNameConvert(FreeSql.Internal.NameConvertType.ToUpper) + + .UseConnectionString(FreeSql.DataType.OdbcDameng, "Driver={DM8 ODBC DRIVER};Server=127.0.0.1:5236;Persist Security Info=False;Trusted_Connection=Yes;UID=USER1;PWD=123456789") + .UseLazyLoading(true) .Build(); BaseEntity.Initialization(fsql); #endregion var test01 = EMSServerModel.Model.User.Select.IncludeMany(a => a.Roles).ToList(); + var test02 = EMSServerModel.Model.UserRole.Select.ToList(); var test01tb = EMSServerModel.Model.User.Orm.CodeFirst.GetTableByEntity(typeof(EMSServerModel.Model.User)); var us = User1.Select.Limit(10).ToList(); diff --git a/Examples/base_entity/Test01/User.cs b/Examples/base_entity/Test01/User.cs index 46dc8e95..be4fbeb2 100644 --- a/Examples/base_entity/Test01/User.cs +++ b/Examples/base_entity/Test01/User.cs @@ -8,10 +8,10 @@ using FreeSql; namespace EMSServerModel.Model { /// - /// 用户表 + /// 用户表bb123123 /// [JsonObject(MemberSerialization.OptIn)] - public partial class User : BaseEntity{ + public partial class User : BaseEntity { //[JsonProperty, Column(IsIdentity = true)] //public long Id { get; set; } diff --git a/Examples/base_entity/Test01/UserRole.cs b/Examples/base_entity/Test01/UserRole.cs index 3c13335a..1d031a08 100644 --- a/Examples/base_entity/Test01/UserRole.cs +++ b/Examples/base_entity/Test01/UserRole.cs @@ -5,12 +5,12 @@ using FreeSql; namespace EMSServerModel.Model { /// - /// ûɫϵ + /// ûɫϵaa111 /// [JsonObject(MemberSerialization.OptIn)] public partial class UserRole : BaseEntity{ /// - /// ɫ + /// ɫ1 /// [JsonProperty] public long RoleId { get; set; } diff --git a/Examples/base_entity/base_entity.csproj b/Examples/base_entity/base_entity.csproj index c912bae3..201c18db 100644 --- a/Examples/base_entity/base_entity.csproj +++ b/Examples/base_entity/base_entity.csproj @@ -21,6 +21,7 @@ + diff --git a/Examples/base_entity/base_entity.xml b/Examples/base_entity/base_entity.xml index a2fd01f9..1241b5ac 100644 --- a/Examples/base_entity/base_entity.xml +++ b/Examples/base_entity/base_entity.xml @@ -61,7 +61,7 @@ - 用户表 + 用户表bb123123 @@ -171,12 +171,12 @@ - 用户角色关系表 + 用户角色关系表aa111 - 角色编号 + 角色编号1 diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index ddd18378..d8bba58b 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -211,15 +211,6 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - 动态Type,在使用 Repository<object> 后使用本方法,指定实体类型 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index d9c8421f..4ec6a7f0 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2309,137 +2309,6 @@ - - - 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 - - - - - - - - - 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) - - - - - - - 查询 - - - - - - - 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) - - - - - - - - 查询 - - - - - - - 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) - - - - - - - - 在【主库】执行 - - - - - - - - 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) - - - - - - - - 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new { age = 25 }) - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) - - - - - - - - - - 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) - - - - - - 可自定义解析表达式 @@ -2963,12 +2832,6 @@ 超时 - - - 获取资源 - - - 使用完毕后,归还资源 @@ -3039,12 +2902,6 @@ 资源对象 - - - 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 - - 资源对象 - 归还对象给对象池的时候触发 diff --git a/FreeSql/FreeSqlBuilder.cs b/FreeSql/FreeSqlBuilder.cs index b3f304fd..800b3900 100644 --- a/FreeSql/FreeSqlBuilder.cs +++ b/FreeSql/FreeSqlBuilder.cs @@ -83,6 +83,7 @@ namespace FreeSql /// /// true:转小写, false:不转 /// + [Obsolete("请使用 UseNameConvert(NameConvertType.ToLower),或者 fsql.CodeFirst.IsSyncStructureToLower = value")] public FreeSqlBuilder UseSyncStructureToLower(bool value) { _isSyncStructureToLower = value; @@ -93,6 +94,7 @@ namespace FreeSql /// /// true:转大写, false:不转 /// + [Obsolete("请使用 UseNameConvert(NameConvertType.ToUpper),或者 fsql.CodeFirst.IsSyncStructureToUpper = value")] public FreeSqlBuilder UseSyncStructureToUpper(bool value) { _isSyncStructureToUpper = value; diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 14a5e3a6..8a59fe20 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -400,11 +400,19 @@ namespace FreeSql.Internal } var xmlNav = xpath.CreateNavigator(); + var className = (type.IsNested ? $"{type.Namespace}.{type.DeclaringType.Name}.{type.Name}" : $"{type.Namespace}.{type.Name}").Trim('.'); + var node = xmlNav.SelectSingleNode($"/doc/members/member[@name='T:{className}']/summary"); + if (node != null) + { + var comment = node.InnerXml.Trim(' ', '\r', '\n', '\t'); + if (string.IsNullOrEmpty(comment) == false) dic.Add("", comment); //class注释 + } + var props = type.GetPropertiesDictIgnoreCase().Values; foreach (var prop in props) { - var className = (prop.DeclaringType.IsNested ? $"{prop.DeclaringType.Namespace}.{prop.DeclaringType.DeclaringType.Name}.{prop.DeclaringType.Name}" : $"{prop.DeclaringType.Namespace}.{prop.DeclaringType.Name}").Trim('.'); - var node = xmlNav.SelectSingleNode($"/doc/members/member[@name='P:{className}.{prop.Name}']/summary"); + className = (prop.DeclaringType.IsNested ? $"{prop.DeclaringType.Namespace}.{prop.DeclaringType.DeclaringType.Name}.{prop.DeclaringType.Name}" : $"{prop.DeclaringType.Namespace}.{prop.DeclaringType.Name}").Trim('.'); + node = xmlNav.SelectSingleNode($"/doc/members/member[@name='P:{className}.{prop.Name}']/summary"); if (node == null) continue; var comment = node.InnerXml.Trim(' ', '\r', '\n', '\t'); if (string.IsNullOrEmpty(comment)) continue; diff --git a/FreeSql/Internal/Model/TableInfo.cs b/FreeSql/Internal/Model/TableInfo.cs index 09223d1d..c882cc72 100644 --- a/FreeSql/Internal/Model/TableInfo.cs +++ b/FreeSql/Internal/Model/TableInfo.cs @@ -22,6 +22,7 @@ namespace FreeSql.Internal.Model public string DbName { get; set; } public string DbOldName { get; set; } public bool DisableSyncStructure { get; set; } + public string Comment { get; internal set; } public ColumnInfo VersionColumn { get; set; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index c77baea9..632a89c6 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -69,6 +69,7 @@ namespace FreeSql.Internal var propsLazy = new List>(); var propsNavObjs = new List(); var propsComment = CommonUtils.GetProperyCommentBySummary(entity); + trytb.Comment = propsComment.TryGetValue("", out var tbcomment) ? tbcomment : ""; var columnsList = new List(); foreach (var p in trytb.Properties.Values) { @@ -370,7 +371,7 @@ namespace FreeSql.Internal foreach (var col in trytb.Primarys) { col.Attribute.IsNullable = false; - col.Attribute.DbType = col.Attribute.DbType.Replace("NOT NULL", ""); + col.Attribute.DbType = col.Attribute.DbType.Replace("NOT NULL", "").Trim(); } foreach (var col in trytb.Columns.Values) { @@ -795,7 +796,14 @@ namespace FreeSql.Internal trytb.AddOrUpdateTableRef(pnv.Name, nvref); if (tbmid.Primarys.Any() == false) + { tbmid.Primarys = tbmid.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); + foreach (var col in tbmid.Primarys) + { + col.Attribute.IsNullable = false; + col.Attribute.DbType = col.Attribute.DbType.Replace("NOT NULL", "").Trim(); + } + } } if (isLazy) diff --git a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs index f96474f4..e48d751f 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlCodeFirst.cs @@ -158,7 +158,10 @@ namespace FreeSql.MySql sb.Remove(sb.Length - 2, 2).Append("),"); } sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) Engine=InnoDB;\r\n"); + sb.Append("\r\n) Engine=InnoDB"); + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append(" Comment=").Append(_commonUtils.FormatSql("{0}", tb.Comment)); + sb.Append(";\r\n"); //创建表的索引 foreach (var uk in tb.Indexes) { @@ -291,6 +294,10 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI } if (istmpatler == false) { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select table_comment from information_schema.tables where table_schema = {0} and table_name = {1}", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(" COMMENT ").Append(" ").Append(_commonUtils.FormatSql("{0}", tb.Comment ?? "")).Append(";\r\n"); + sb.Append(sbalter); continue; } @@ -314,7 +321,11 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI sb.Remove(sb.Length - 2, 2).Append("),"); } sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) Engine=InnoDB;\r\n"); + sb.Append("\r\n) Engine=InnoDB"); + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append(" Comment=").Append(_commonUtils.FormatSql("{0}", tb.Comment)); + sb.Append(";\r\n"); + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs index 2edc8107..b28aad3f 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengCodeFirst.cs @@ -165,6 +165,8 @@ namespace FreeSql.Odbc.Dameng if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); continue; } //如果新表,旧表在一个模式下,直接修改表名 @@ -189,8 +191,8 @@ a.data_precision, a.data_scale, a.char_used, case when a.nullable = 'N' then 0 else 1 end, -nvl((select 1 from user_sequences where sequence_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name), 0), -nvl((select 1 from user_triggers where trigger_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI'), 0), +nvl((select 1 from user_sequences where upper(sequence_name)=upper('{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name) and rownum < 2), 0), +nvl((select 1 from user_triggers where upper(trigger_name)=upper('{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI') and rownum < 2), 0), b.comments from all_tab_columns a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name @@ -219,7 +221,15 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); { var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { istmpatler = true; + if (istmpatler && tbcol.Attribute.DbType.StartsWith("varchar", StringComparison.CurrentCultureIgnoreCase) && tbstructcol.sqlType.StartsWith("varchar2", StringComparison.CurrentCultureIgnoreCase) + && Regex.Match(tbcol.Attribute.DbType, @"\(\d+").Groups[0].Value == Regex.Match(tbstructcol.sqlType, @"\(\d+").Groups[0].Value) + istmpatler = false; + if (istmpatler && Regex.IsMatch(tbcol.Attribute.DbType, @"\(\d+") == false && Regex.IsMatch(tbstructcol.sqlType, @"\(\d+") + && string.Compare(tbcol.Attribute.DbType, Regex.Replace(tbstructcol.sqlType, @"\([^\)]+\)", ""), StringComparison.CurrentCultureIgnoreCase) == 0) + istmpatler = false; + } //sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { @@ -289,6 +299,10 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and } if (istmpatler == false) { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select comments from all_tab_comments where owner = {0} and table_name = {1} and table_type = 'TABLE'", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); + sb.Append(sbalter); continue; } @@ -321,6 +335,9 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); + sb.Append("execute immediate 'INSERT INTO ").Append(tmptablename).Append(" ("); foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); @@ -397,7 +414,7 @@ and not exists(select 1 from all_constraints where index_name = a.index_name and foreach (var seqcol in seqcols) { var tbname = seqcol.Item2; - var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}"); + var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}").ToUpper(); var tiggerName = seqname + "TI"; var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs index 94b34597..3e389fb6 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlCodeFirst.cs @@ -151,7 +151,10 @@ namespace FreeSql.Odbc.MySql sb.Remove(sb.Length - 2, 2).Append("),"); } sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) Engine=InnoDB;\r\n"); + sb.Append("\r\n) Engine=InnoDB"); + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append(" Comment=").Append(_commonUtils.FormatSql("{0}", tb.Comment)); + sb.Append(";\r\n"); //创建表的索引 foreach (var uk in tb.Indexes) { @@ -284,6 +287,10 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI } if (istmpatler == false) { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select table_comment from information_schema.tables where table_schema = {0} and table_name = {1}", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])).Append(" COMMENT ").Append(" ").Append(_commonUtils.FormatSql("{0}", tb.Comment ?? "")).Append(";\r\n"); + sb.Append(sbalter); continue; } @@ -307,7 +314,11 @@ where a.table_schema IN ({0}) and a.table_name IN ({1}) and a.index_name <> 'PRI sb.Remove(sb.Length - 2, 2).Append("),"); } sb.Remove(sb.Length - 1, 1); - sb.Append("\r\n) Engine=InnoDB;\r\n"); + sb.Append("\r\n) Engine=InnoDB"); + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append(" Comment=").Append(_commonUtils.FormatSql("{0}", tb.Comment)); + sb.Append(";\r\n"); + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs index adec255e..f741ef1b 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleCodeFirst.cs @@ -165,6 +165,8 @@ namespace FreeSql.Odbc.Oracle if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); continue; } //如果新表,旧表在一个模式下,直接修改表名 @@ -189,8 +191,8 @@ a.data_precision, a.data_scale, a.char_used, case when a.nullable = 'N' then 0 else 1 end, -nvl((select 1 from user_sequences where sequence_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name), 0), -nvl((select 1 from user_triggers where trigger_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI'), 0), +nvl((select 1 from user_sequences where upper(sequence_name)=upper('{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name) and rownum < 2), 0), +nvl((select 1 from user_triggers where upper(trigger_name)=upper('{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI') and rownum < 2), 0), b.comments from all_tab_columns a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name @@ -219,7 +221,12 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); { var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { istmpatler = true; + if (tbcol.Attribute.DbType.StartsWith("varchar", StringComparison.CurrentCultureIgnoreCase) && tbstructcol.sqlType.StartsWith("varchar2", StringComparison.CurrentCultureIgnoreCase) + && Regex.Match(tbcol.Attribute.DbType, @"\(\d+").Groups[0].Value == Regex.Match(tbstructcol.sqlType, @"\(\d+").Groups[0].Value) + istmpatler = false; + } //sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { @@ -290,6 +297,10 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam } if (istmpatler == false) { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select comments from all_tab_comments where owner = {0} and table_name = {1} and table_type = 'TABLE'", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); + sb.Append(sbalter); continue; } @@ -322,6 +333,9 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); + sb.Append("execute immediate 'INSERT INTO ").Append(tmptablename).Append(" ("); foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); @@ -398,7 +412,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam foreach (var seqcol in seqcols) { var tbname = seqcol.Item2; - var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}"); + var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}").ToUpper(); var tiggerName = seqname + "TI"; var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); @@ -440,6 +454,12 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam else if (sqlType.StartsWith("BLOB")) { } + else if (sqlType.StartsWith("CLOB")) + { + } + else if (sqlType.StartsWith("NCLOB")) + { + } else if (char_used.ToLower() == "c") sqlType += sqlType.StartsWith("N") ? $"({data_length / 2})" : $"({data_length / 4} CHAR)"; else if (char_used.ToLower() == "b") diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs index 14f4821d..bbc2d5e9 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLCodeFirst.cs @@ -158,6 +158,8 @@ namespace FreeSql.Odbc.PostgreSQL if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); continue; } //如果新表,旧表在一个数据库和模式下,直接修改表名 @@ -180,7 +182,7 @@ t.typname, case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, case when t.typelem > 0 and t.typinput::varchar = 'array_in' then t2.typname else t.typname end, case when a.attnotnull then '0' else '1' end as is_nullable, -coalesce((select 1 from pg_sequences where sequencename = {0} || '_' || {1} || '_' || a.attname || '_sequence_name' limit 1),0) is_identity, +coalesce((select 1 from pg_sequences where lower(sequencename) = lower({0} || '_' || {1} || '_' || a.attname || '_sequence_name') limit 1),0) is_identity, --e.adsrc, a.attndims, d.description as comment @@ -294,6 +296,16 @@ where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tbol } if (istmpatler == false) { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select +d.description +from pg_class a +inner join pg_namespace b on b.oid = a.relnamespace +left join pg_description d on d.objoid = a.oid and objsubid = 0 +where b.nspname not in ('pg_catalog', 'information_schema') and a.relkind in ('r') and b.nspname = {0} and a.relname = {1} +and b.nspname || '.' || a.relname not in ('public.geography_columns','public.geometry_columns','public.raster_columns','public.raster_overviews')", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + sb.Append(sbalter); continue; } @@ -329,6 +341,9 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); @@ -370,7 +385,7 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp foreach (var seqcol in seqcols) { var tbname = seqcol.Item2; - var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_sequence_name"); + var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_sequence_name").ToLower(); ; var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT null;\r\n"); diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs index 097a63ed..913ae1c3 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLDbFirst.cs @@ -209,7 +209,7 @@ t.typname, case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, case when t.typelem = 0 then t.typname else t2.typname end, case when a.attnotnull then 0 else 1 end as is_nullable, -coalesce((select 1 from pg_sequences where sequencename = {0} || '_' || {1} || '_' || a.attname || '_sequence_name' limit 1),0) is_identity, +coalesce((select 1 from pg_sequences where lower(sequencename) = lower({0} || '_' || {1} || '_' || a.attname || '_sequence_name') limit 1),0) is_identity, --e.adsrc as is_identity, d.description as comment, a.attndims, diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs index 9633d8db..550903f3 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerCodeFirst.cs @@ -71,6 +71,35 @@ namespace FreeSql.Odbc.SqlServer return null; } + void AddOrUpdateMS_Description(StringBuilder sb, string schema, string table, string comment) + { + if (string.IsNullOrEmpty(comment)) + { + sb.AppendFormat(@" +IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', + 'SCHEMA', N'{0}', + 'TABLE', N'{1}', + NULL, NULL)) > 0) + EXEC sp_dropextendedproperty @name = N'MS_Description' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' +", schema.Replace("'", "''"), table.Replace("'", "''")); + return; + } + sb.AppendFormat(@" +IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', + 'SCHEMA', N'{0}', + 'TABLE', N'{1}', + NULL, NULL)) > 0) + EXEC sp_updateextendedproperty @name = N'MS_Description', @value = N'{2}' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' +ELSE + EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'{2}' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' +", schema.Replace("'", "''"), table.Replace("'", "''"), comment?.Replace("'", "''") ?? ""); + } void AddOrUpdateMS_Description(StringBuilder sb, string schema, string table, string column, string comment) { if (string.IsNullOrEmpty(comment)) @@ -216,6 +245,8 @@ ELSE if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); } + if (string.IsNullOrEmpty(tb.Comment) == false) + AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tb.Comment); continue; } //如果新表,旧表在一个数据库和模式下,直接修改表名 @@ -327,6 +358,10 @@ use [" + database + "];", tboldname ?? tbname); } if (istmpatler == false) { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, $" SELECT value from fn_listextendedproperty('MS_Description', 'schema', N'{tbname[1].Replace("'", "''")}', 'table', N'{tbname[2].Replace("'", "''")}', NULL, NULL)")); + if (dbcomment != (tb.Comment ?? "")) + AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tb.Comment); + if (sbalter.Length > 0) sb.Append(sbalter).Append("\r\nuse " + database); continue; @@ -373,6 +408,9 @@ use [" + database + "];", tboldname ?? tbname); if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sb, tbname[1], $"FreeSqlTmp_{tbname[2]}", tbcol.Attribute.Name, tbcol.Comment); } + if (string.IsNullOrEmpty(tb.Comment) == false) + AddOrUpdateMS_Description(sb, tbname[1], $"FreeSqlTmp_{tbname[2]}", tb.Comment); + if ((_commonUtils as OdbcSqlServerUtils).ServerVersion > 9) //SqlServer 2008+ sb.Append("ALTER TABLE ").Append(tmptablename).Append(" SET (LOCK_ESCALATION = TABLE);\r\n"); if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" ON;\r\n"); diff --git a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs index 149011e7..b28bc7a2 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleCodeFirst.cs @@ -166,6 +166,8 @@ namespace FreeSql.Oracle if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); continue; } //如果新表,旧表在一个模式下,直接修改表名 @@ -190,8 +192,8 @@ a.data_precision, a.data_scale, a.char_used, case when a.nullable = 'N' then 0 else 1 end, -nvl((select 1 from user_sequences where sequence_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name), 0), -nvl((select 1 from user_triggers where trigger_name='{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI'), 0), +nvl((select 1 from user_sequences where upper(sequence_name)=upper('{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name) and rownum < 2), 0), +nvl((select 1 from user_triggers where upper(trigger_name)=upper('{Utils.GetCsName((tboldname ?? tbname).Last())}_seq_'||a.column_name||'TI') and rownum < 2), 0), b.comments from all_tab_columns a left join all_col_comments b on b.owner = a.owner and b.table_name = a.table_name and b.column_name = a.column_name @@ -220,7 +222,12 @@ where a.owner={{0}} and a.table_name={{1}}", tboldname ?? tbname); { var isCommentChanged = tbstructcol.comment != (tbcol.Comment ?? ""); if (tbcol.Attribute.DbType.StartsWith(tbstructcol.sqlType, StringComparison.CurrentCultureIgnoreCase) == false) + { istmpatler = true; + if (tbcol.Attribute.DbType.StartsWith("varchar", StringComparison.CurrentCultureIgnoreCase) && tbstructcol.sqlType.StartsWith("varchar2", StringComparison.CurrentCultureIgnoreCase) + && Regex.Match(tbcol.Attribute.DbType, @"\(\d+").Groups[0].Value == Regex.Match(tbstructcol.sqlType, @"\(\d+").Groups[0].Value) + istmpatler = false; + } //sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" MODIFY (").Append(_commonUtils.QuoteSqlName(tbstructcol.column)).Append(" ").Append(dbtypeNoneNotNull).Append(")';\r\n"); if (tbcol.Attribute.IsNullable != tbstructcol.is_nullable) { @@ -291,6 +298,10 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam } if (istmpatler == false) { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select comments from all_tab_comments where owner = {0} and table_name = {1} and table_type = 'TABLE'", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); + sb.Append(sbalter); continue; } @@ -323,6 +334,9 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("execute immediate 'COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment).Replace("'", "''")).Append("';\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("execute immediate 'COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FTmp_{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment).Replace("'", "''")).Append("';\r\n"); + sb.Append("execute immediate 'INSERT INTO ").Append(tmptablename).Append(" ("); foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); @@ -399,7 +413,7 @@ and not exists(select 1 from all_constraints where constraint_name = a.index_nam foreach (var seqcol in seqcols) { var tbname = seqcol.Item2; - var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}"); + var seqname = Utils.GetCsName($"{tbname[1]}_seq_{seqcol.Item1.Attribute.Name}").ToUpper(); var tiggerName = seqname + "TI"; var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs index 70011c5a..e5a65693 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLCodeFirst.cs @@ -193,6 +193,8 @@ namespace FreeSql.PostgreSQL if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); continue; } //如果新表,旧表在一个数据库和模式下,直接修改表名 @@ -215,7 +217,7 @@ t.typname, case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, case when t.typelem > 0 and t.typinput::varchar = 'array_in' then t2.typname else t.typname end, case when a.attnotnull then '0' else '1' end as is_nullable, -coalesce((select 1 from pg_sequences where sequencename = {0} || '_' || {1} || '_' || a.attname || '_sequence_name' limit 1),0) is_identity, +coalesce((select 1 from pg_sequences where lower(sequencename) = lower({0} || '_' || {1} || '_' || a.attname || '_sequence_name') limit 1),0) is_identity, --e.adsrc, a.attndims, d.description as comment @@ -329,6 +331,16 @@ where ns.nspname in ({0}) and d.relname in ({1}) and a.indisprimary = 'f'", tbol } if (istmpatler == false) { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, _commonUtils.FormatSql(@" select +d.description +from pg_class a +inner join pg_namespace b on b.oid = a.relnamespace +left join pg_description d on d.objoid = a.oid and objsubid = 0 +where b.nspname not in ('pg_catalog', 'information_schema') and a.relkind in ('r') and b.nspname = {0} and a.relname = {1} +and b.nspname || '.' || a.relname not in ('public.geography_columns','public.geometry_columns','public.raster_columns','public.raster_overviews')", tbname[0], tbname[1]))); + if (dbcomment != (tb.Comment ?? "")) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + sb.Append(sbalter); continue; } @@ -364,6 +376,9 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp if (string.IsNullOrEmpty(tbcol.Comment) == false) sb.Append("COMMENT ON COLUMN ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}.{tbcol.Attribute.Name}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tbcol.Comment)).Append(";\r\n"); } + if (string.IsNullOrEmpty(tb.Comment) == false) + sb.Append("COMMENT ON TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.FreeSqlTmp_{tbname[1]}")).Append(" IS ").Append(_commonUtils.FormatSql("{0}", tb.Comment)).Append(";\r\n"); + sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); foreach (var tbcol in tb.ColumnsByPosition) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); @@ -405,7 +420,7 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp foreach (var seqcol in seqcols) { var tbname = seqcol.Item2; - var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_sequence_name"); + var seqname = Utils.GetCsName($"{tbname[0]}.{tbname[1]}_{seqcol.Item1.Attribute.Name}_sequence_name").ToLower(); var tbname2 = _commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}"); var colname2 = _commonUtils.QuoteSqlName(seqcol.Item1.Attribute.Name); sb.Append("ALTER TABLE ").Append(tbname2).Append(" ALTER COLUMN ").Append(colname2).Append(" SET DEFAULT null;\r\n"); diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index f5cbc3a0..eb586c98 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -319,7 +319,7 @@ t.typname, case when a.atttypmod > 0 and a.atttypmod < 32767 then a.atttypmod - 4 else a.attlen end len, case when t.typelem = 0 then t.typname else t2.typname end, case when a.attnotnull then 0 else 1 end as is_nullable, -coalesce((select 1 from pg_sequences where sequencename = {0} || '_' || {1} || '_' || a.attname || '_sequence_name' limit 1),0) is_identity, +coalesce((select 1 from pg_sequences where lower(sequencename) = lower({0} || '_' || {1} || '_' || a.attname || '_sequence_name') limit 1),0) is_identity, --e.adsrc as is_identity, d.description as comment, a.attndims, diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs index 00cdc6f0..2d30c5ba 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerCodeFirst.cs @@ -70,6 +70,35 @@ namespace FreeSql.SqlServer return null; } + void AddOrUpdateMS_Description(StringBuilder sb, string schema, string table, string comment) + { + if (string.IsNullOrEmpty(comment)) + { + sb.AppendFormat(@" +IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', + 'SCHEMA', N'{0}', + 'TABLE', N'{1}', + NULL, NULL)) > 0) + EXEC sp_dropextendedproperty @name = N'MS_Description' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' +", schema.Replace("'", "''"), table.Replace("'", "''")); + return; + } + sb.AppendFormat(@" +IF ((SELECT COUNT(1) from fn_listextendedproperty('MS_Description', + 'SCHEMA', N'{0}', + 'TABLE', N'{1}', + NULL, NULL)) > 0) + EXEC sp_updateextendedproperty @name = N'MS_Description', @value = N'{2}' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' +ELSE + EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'{2}' + , @level0type = 'SCHEMA', @level0name = N'{0}' + , @level1type = 'TABLE', @level1name = N'{1}' +", schema.Replace("'", "''"), table.Replace("'", "''"), comment?.Replace("'", "''") ?? ""); + } void AddOrUpdateMS_Description(StringBuilder sb, string schema, string table, string column, string comment) { if (string.IsNullOrEmpty(comment)) @@ -215,6 +244,8 @@ ELSE if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tbcol.Attribute.Name, tbcol.Comment); } + if (string.IsNullOrEmpty(tb.Comment) == false) + AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tb.Comment); continue; } //如果新表,旧表在一个数据库和模式下,直接修改表名 @@ -326,6 +357,10 @@ use [" + database + "];", tboldname ?? tbname); } if (istmpatler == false) { + var dbcomment = string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, $" SELECT value from fn_listextendedproperty('MS_Description', 'schema', N'{tbname[1].Replace("'", "''")}', 'table', N'{tbname[2].Replace("'", "''")}', NULL, NULL)")); + if (dbcomment != (tb.Comment ?? "")) + AddOrUpdateMS_Description(sb, tbname[1], tbname[2], tb.Comment); + if (sbalter.Length > 0) sb.Append(sbalter).Append("\r\nuse " + database); continue; @@ -372,6 +407,9 @@ use [" + database + "];", tboldname ?? tbname); if (string.IsNullOrEmpty(tbcol.Comment) == false) AddOrUpdateMS_Description(sb, tbname[1], $"FreeSqlTmp_{tbname[2]}", tbcol.Attribute.Name, tbcol.Comment); } + if (string.IsNullOrEmpty(tb.Comment) == false) + AddOrUpdateMS_Description(sb, tbname[1], $"FreeSqlTmp_{tbname[2]}", tb.Comment); + if ((_commonUtils as SqlServerUtils).ServerVersion > 9) //SqlServer 2008+ sb.Append("ALTER TABLE ").Append(tmptablename).Append(" SET (LOCK_ESCALATION = TABLE);\r\n"); if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" ON;\r\n");