增加 Column.Unique 唯一键 #42

This commit is contained in:
28810 2019-04-26 23:14:20 +08:00
parent 5bb90a974b
commit 45b785f43b
18 changed files with 300 additions and 46 deletions

View File

@ -9,6 +9,25 @@ using Xunit;
namespace FreeSql.Tests.MySql { namespace FreeSql.Tests.MySql {
public class MySqlCodeFirstTest { public class MySqlCodeFirstTest {
[Fact]
public void AddUniques() {
var sql = g.mysql.CodeFirst.GetComparisonDDLStatements<AddUniquesInfo>();
g.mysql.CodeFirst.SyncStructure<AddUniquesInfo>();
}
[Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")]
class AddUniquesInfo {
public Guid id { get; set; }
[Column(Unique = "uk_phone")]
public string phone { get; set; }
[Column(Unique = "uk_group_index")]
public string group { get; set; }
[Column(Unique = "uk_group_index11")]
public int index { get; set; }
[Column(Unique = "uk_group_index222")]
public string index22 { get; set; }
}
[Fact] [Fact]
public void AddField() { public void AddField() {
var sql = g.mysql.CodeFirst.GetComparisonDDLStatements<TopicAddField>(); var sql = g.mysql.CodeFirst.GetComparisonDDLStatements<TopicAddField>();

View File

@ -9,6 +9,24 @@ using Xunit;
namespace FreeSql.Tests.Oracle { namespace FreeSql.Tests.Oracle {
public class OracleCodeFirstTest { public class OracleCodeFirstTest {
[Fact]
public void AddUniques() {
var sql = g.oracle.CodeFirst.GetComparisonDDLStatements<AddUniquesInfo>();
g.oracle.CodeFirst.SyncStructure<AddUniquesInfo>();
}
[Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")]
class AddUniquesInfo {
public Guid id { get; set; }
[Column(Unique = "uk_phone")]
public string phone { get; set; }
[Column(Unique = "uk_group_index")]
public string group { get; set; }
[Column(Unique = "uk_group_index11")]
public int index { get; set; }
[Column(Unique = "uk_group_index222")]
public string index22 { get; set; }
}
[Fact] [Fact]
public void AddField() { public void AddField() {
var sql = g.oracle.CodeFirst.GetComparisonDDLStatements<TopicAddField>(); var sql = g.oracle.CodeFirst.GetComparisonDDLStatements<TopicAddField>();

View File

@ -16,6 +16,25 @@ using Xunit;
namespace FreeSql.Tests.PostgreSQL { namespace FreeSql.Tests.PostgreSQL {
public class PostgreSQLCodeFirstTest { public class PostgreSQLCodeFirstTest {
[Fact]
public void AddUniques() {
var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements<AddUniquesInfo>();
g.pgsql.CodeFirst.SyncStructure<AddUniquesInfo>();
}
[Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")]
class AddUniquesInfo {
public Guid id { get; set; }
[Column(Unique = "uk_phone")]
public string phone { get; set; }
[Column(Unique = "uk_group_index")]
public string group { get; set; }
[Column(Unique = "uk_group_index11")]
public int index { get; set; }
[Column(Unique = "uk_group_index222")]
public string index22 { get; set; }
}
[Fact] [Fact]
public void AddField() { public void AddField() {
var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements<TopicAddField>(); var sql = g.pgsql.CodeFirst.GetComparisonDDLStatements<TopicAddField>();

View File

@ -19,6 +19,25 @@ namespace FreeSql.Tests.SqlServer {
_sqlserverFixture = sqlserverFixture; _sqlserverFixture = sqlserverFixture;
} }
[Fact]
public void AddUniques() {
var sql = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements<AddUniquesInfo>();
_sqlserverFixture.SqlServer.CodeFirst.SyncStructure<AddUniquesInfo>();
}
[Table(Name = "AddUniquesInfo", OldName = "AddUniquesInfo2")]
class AddUniquesInfo {
public Guid id { get; set; }
[Column(Unique = "uk_phone")]
public string phone { get; set; }
[Column(Unique = "uk_group_index")]
public string group { get; set; }
[Column(Unique = "uk_group_index11")]
public int index { get; set; }
[Column(Unique = "uk_group_index222")]
public string index22 { get; set; }
}
[Fact] [Fact]
public void AddField() { public void AddField() {
var sql = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements<TopicAddField>(); var sql = _sqlserverFixture.SqlServer.CodeFirst.GetComparisonDDLStatements<TopicAddField>();

View File

@ -24,7 +24,7 @@ namespace FreeSql.Tests.SqlServer {
[Fact] [Fact]
public void GetTablesByDatabase() { public void GetTablesByDatabase() {
var t2 = _sqlserverFixture.SqlServer.DbFirst.GetTablesByDatabase(_sqlserverFixture.SqlServer.DbFirst.GetDatabases()[0]); var t2 = _sqlserverFixture.SqlServer.DbFirst.GetTablesByDatabase();
} }
} }

View File

@ -10,6 +10,25 @@ namespace FreeSql.Tests.Sqlite {
public class SqliteCodeFirstTest { public class SqliteCodeFirstTest {
[Fact]
public void AddUniques() {
var sql = g.sqlite.CodeFirst.GetComparisonDDLStatements<AddUniquesInfo>();
g.sqlite.CodeFirst.SyncStructure<AddUniquesInfo>();
}
[Table(Name = "AddUniquesInfo2", OldName = "AddUniquesInfo")]
class AddUniquesInfo {
public Guid id { get; set; }
[Column(Unique = "uk_phone")]
public string phone { get; set; }
[Column(Unique = "uk_group_index")]
public string group { get; set; }
[Column(Unique = "uk_group_index111")]
public int index { get; set; }
[Column(Unique = "uk_group_index222")]
public string index22 { get; set; }
}
public class Topic { public class Topic {
public Guid Id { get; set; } public Guid Id { get; set; }
public string Title { get; set; } public string Title { get; set; }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Concurrent;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace FreeSql.Internal.CommonProvider { namespace FreeSql.Internal.CommonProvider {
@ -10,10 +11,12 @@ namespace FreeSql.Internal.CommonProvider {
var nparms = new object[parms.Length]; var nparms = new object[parms.Length];
for (int a = 0; a < parms.Length; a++) { for (int a = 0; a < parms.Length; a++) {
if (parms[a] == null) if (parms[a] == null)
filter = Regex.Replace(filter, @"\s*(=|IN)\s*\{" + a + @"\}", " IS {" + a + "}", RegexOptions.IgnoreCase); filter = _dicAddslashesReplaceIsNull.GetOrAdd(a, b => new Regex(@"\s*(=|IN)\s*\{" + b + @"\}", RegexOptions.IgnoreCase | RegexOptions.Compiled))
.Replace(filter, $" IS {{{a}}}");
nparms[a] = AddslashesProcessParam(parms[a], null); nparms[a] = AddslashesProcessParam(parms[a], null);
} }
try { string ret = string.Format(filter, nparms); return ret; } catch { return filter; } try { string ret = string.Format(filter, nparms); return ret; } catch { return filter; }
} }
static ConcurrentDictionary<int, Regex> _dicAddslashesReplaceIsNull = new ConcurrentDictionary<int, Regex>();
} }
} }

View File

@ -101,6 +101,7 @@ namespace FreeSql.Internal {
if (trycol._IsNullable != null) attr._IsNullable = trycol.IsNullable; if (trycol._IsNullable != null) attr._IsNullable = trycol.IsNullable;
if (trycol._IsIgnore != null) attr._IsIgnore = trycol.IsIgnore; if (trycol._IsIgnore != null) attr._IsIgnore = trycol.IsIgnore;
if (trycol._IsVersion != null) attr._IsVersion = trycol.IsVersion; if (trycol._IsVersion != null) attr._IsVersion = trycol.IsVersion;
if (!string.IsNullOrEmpty(trycol.Unique)) attr.Unique = trycol.Unique;
if (trycol.MapType != null) attr.MapType = trycol.MapType; if (trycol.MapType != null) attr.MapType = trycol.MapType;
if (trycol.DbDefautValue != null) attr.DbDefautValue = trycol.DbDefautValue; if (trycol.DbDefautValue != null) attr.DbDefautValue = trycol.DbDefautValue;
} }
@ -116,6 +117,7 @@ namespace FreeSql.Internal {
if (tryattr._IsNullable != null) attr._IsNullable = tryattr.IsNullable; if (tryattr._IsNullable != null) attr._IsNullable = tryattr.IsNullable;
if (tryattr._IsIgnore != null) attr._IsIgnore = tryattr.IsIgnore; if (tryattr._IsIgnore != null) attr._IsIgnore = tryattr.IsIgnore;
if (tryattr._IsVersion != null) attr._IsVersion = tryattr.IsVersion; if (tryattr._IsVersion != null) attr._IsVersion = tryattr.IsVersion;
if (!string.IsNullOrEmpty(tryattr.Unique)) attr.Unique = tryattr.Unique;
if (tryattr.MapType != null) attr.MapType = tryattr.MapType; if (tryattr.MapType != null) attr.MapType = tryattr.MapType;
if (tryattr.DbDefautValue != null) attr.DbDefautValue = tryattr.DbDefautValue; if (tryattr.DbDefautValue != null) attr.DbDefautValue = tryattr.DbDefautValue;
} }
@ -128,6 +130,7 @@ namespace FreeSql.Internal {
if (attr._IsNullable != null) ret = attr; if (attr._IsNullable != null) ret = attr;
if (attr._IsIgnore != null) ret = attr; if (attr._IsIgnore != null) ret = attr;
if (attr._IsVersion != null) ret = attr; if (attr._IsVersion != null) ret = attr;
if (!string.IsNullOrEmpty(attr.Unique)) ret = attr;
if (attr.MapType != null) ret = attr; if (attr.MapType != null) ret = attr;
if (attr.DbDefautValue != null) ret = attr; if (attr.DbDefautValue != null) ret = attr;
if (ret != null && ret.MapType == null) ret.MapType = proto.PropertyType; if (ret != null && ret.MapType == null) ret.MapType = proto.PropertyType;

View File

@ -18,7 +18,11 @@ namespace FreeSql.Internal {
static ConcurrentDictionary<DataType, ConcurrentDictionary<Type, TableInfo>> _cacheGetTableByEntity = new ConcurrentDictionary<DataType, ConcurrentDictionary<Type, TableInfo>>(); static ConcurrentDictionary<DataType, ConcurrentDictionary<Type, TableInfo>> _cacheGetTableByEntity = new ConcurrentDictionary<DataType, ConcurrentDictionary<Type, TableInfo>>();
internal static void RemoveTableByEntity(Type entity, CommonUtils common) { internal static void RemoveTableByEntity(Type entity, CommonUtils common) {
if (entity.FullName.StartsWith("<>f__AnonymousType")) return; if (entity.FullName.StartsWith("<>f__AnonymousType") ||
entity.IsValueType ||
entity.IsNullableType() ||
entity.NullableTypeOrThis() == typeof(BigInteger)
) return;
var tbc = _cacheGetTableByEntity.GetOrAdd(common._orm.Ado.DataType, k1 => new ConcurrentDictionary<Type, TableInfo>()); //区分数据库类型缓存 var tbc = _cacheGetTableByEntity.GetOrAdd(common._orm.Ado.DataType, k1 => new ConcurrentDictionary<Type, TableInfo>()); //区分数据库类型缓存
if (tbc.TryRemove(entity, out var trytb) && trytb?.TypeLazy != null) tbc.TryRemove(trytb.TypeLazy, out var trylz); if (tbc.TryRemove(entity, out var trytb) && trytb?.TypeLazy != null) tbc.TryRemove(trytb.TypeLazy, out var trylz);
} }
@ -75,6 +79,7 @@ namespace FreeSql.Internal {
IsNullable = tp.Value.isnullable ?? true, IsNullable = tp.Value.isnullable ?? true,
IsPrimary = false, IsPrimary = false,
IsIgnore = false, IsIgnore = false,
Unique = null,
MapType = p.PropertyType MapType = p.PropertyType
}; };
if (colattr._IsNullable == null) colattr._IsNullable = tp?.isnullable; if (colattr._IsNullable == null) colattr._IsNullable = tp?.isnullable;
@ -84,8 +89,14 @@ namespace FreeSql.Internal {
if (tp != null && tp.Value.isnullable == null) colattr.IsNullable = tp.Value.dbtypeFull.Contains("NOT NULL") == false; if (tp != null && tp.Value.isnullable == null) colattr.IsNullable = tp.Value.dbtypeFull.Contains("NOT NULL") == false;
if (colattr.DbType?.Contains("NOT NULL") == true) colattr.IsNullable = false; if (colattr.DbType?.Contains("NOT NULL") == true) colattr.IsNullable = false;
if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name; if (string.IsNullOrEmpty(colattr.Name)) colattr.Name = p.Name;
if (common.CodeFirst.IsSyncStructureToLower) colattr.Name = colattr.Name.ToLower(); if (common.CodeFirst.IsSyncStructureToLower) {
if (common.CodeFirst.IsSyncStructureToUpper) colattr.Name = colattr.Name.ToUpper(); colattr.Name = colattr.Name.ToLower();
if (!string.IsNullOrEmpty(colattr.Unique)) colattr.Unique = colattr.Unique.ToLower();
}
if (common.CodeFirst.IsSyncStructureToUpper) {
colattr.Name = colattr.Name.ToUpper();
if (!string.IsNullOrEmpty(colattr.Unique)) colattr.Unique = colattr.Unique.ToUpper();
}
if ((colattr.IsNullable != true || colattr.IsIdentity == true || colattr.IsPrimary == true) && colattr.DbType.Contains("NOT NULL") == false) { if ((colattr.IsNullable != true || colattr.IsIdentity == true || colattr.IsPrimary == true) && colattr.DbType.Contains("NOT NULL") == false) {
colattr.IsNullable = false; colattr.IsNullable = false;
@ -177,8 +188,8 @@ namespace FreeSql.Internal {
} catch { } } catch { }
trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray();
} }
trytb.Uniques = trytb.Columns.Values.Where(a => !string.IsNullOrEmpty(a.Attribute.Unique)) trytb.Uniques = trytb.Columns.Values.Where(a => !string.IsNullOrEmpty(a.Attribute.Unique)).Select(a => a.Attribute.Unique).Distinct()
.ToDictionary(a => a.Attribute.Unique, a => trytb.Columns.Values.Where(b => b.Attribute.Unique == a.Attribute.Unique).ToList()); .ToDictionary(a => a, a => trytb.Columns.Values.Where(b => b.Attribute.Unique == a).ToList());
tbc.AddOrUpdate(entity, trytb, (oldkey, oldval) => trytb); tbc.AddOrUpdate(entity, trytb, (oldkey, oldval) => trytb);
#region virtual #region virtual

View File

@ -133,13 +133,17 @@ namespace FreeSql.MySql {
if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT");
sb.Append(","); sb.Append(",");
} }
if (tb.Primarys.Any() == false) if (tb.Primarys.Any()) {
sb.Remove(sb.Length - 1, 1);
else {
sb.Append(" \r\n PRIMARY KEY ("); sb.Append(" \r\n PRIMARY KEY (");
foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append(")"); sb.Remove(sb.Length - 2, 2).Append("),");
} }
foreach (var uk in tb.Uniques) {
sb.Append(" \r\n UNIQUE KEY ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("(");
foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append("),");
}
sb.Remove(sb.Length - 1, 1);
sb.Append("\r\n) Engine=InnoDB CHARACTER SET utf8;\r\n"); sb.Append("\r\n) Engine=InnoDB CHARACTER SET utf8;\r\n");
continue; continue;
} }
@ -176,7 +180,7 @@ where a.table_schema in ({0}) and a.table_name in ({1})".FormatMySql(tboldname ?
}, StringComparer.CurrentCultureIgnoreCase); }, StringComparer.CurrentCultureIgnoreCase);
if (istmpatler == false) { if (istmpatler == false) {
var existsPrimary = ExecuteScalar(tbname[0], "select 1 from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where table_schema={0} and table_name={1} limit 1".FormatMySql(tbname)); var existsPrimary = ExecuteScalar(tbname[0], "select 1 from information_schema.key_column_usage where table_schema={0} and table_name={1} and constraint_name = 'PRIMARY' limit 1".FormatMySql(tbname));
foreach (var tbcol in tb.Columns.Values) { foreach (var tbcol in tb.Columns.Values) {
var isIdentityChanged = tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1; var isIdentityChanged = tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1;
if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) || if (tbstruct.TryGetValue(tbcol.Attribute.Name, out var tbstructcol) ||
@ -202,6 +206,23 @@ where a.table_schema in ({0}) and a.table_name in ({1})".FormatMySql(tboldname ?
if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")"); if (isIdentityChanged) sbalter.Append(" AUTO_INCREMENT").Append(existsPrimary == null ? "" : ", DROP PRIMARY KEY").Append(", ADD PRIMARY KEY(").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(")");
sbalter.Append(";\r\n"); sbalter.Append(";\r\n");
} }
var dsuksql = @"
select
a.column_name,
a.constraint_name 'index_id'
from information_schema.key_column_usage a
where a.constraint_schema IN ({0}) and a.table_name IN ({1})".FormatMySql(tboldname ?? tbname);
var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) });
foreach (var uk in tb.Uniques) {
if (uk.Key == "PRIMARY" || string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue;
var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray();
if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) {
if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP INDEX ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n");
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE(");
foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n");
}
}
} }
if (istmpatler == false) { if (istmpatler == false) {
sb.Append(sbalter); sb.Append(sbalter);
@ -219,13 +240,17 @@ where a.table_schema in ({0}) and a.table_name in ({1})".FormatMySql(tboldname ?
if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT"); if (tbcol.Attribute.IsIdentity == true && tbcol.Attribute.DbType.IndexOf("AUTO_INCREMENT", StringComparison.CurrentCultureIgnoreCase) == -1) sb.Append(" AUTO_INCREMENT");
sb.Append(","); sb.Append(",");
} }
if (tb.Primarys.Any() == false) if (tb.Primarys.Any()) {
sb.Remove(sb.Length - 1, 1);
else {
sb.Append(" \r\n PRIMARY KEY ("); sb.Append(" \r\n PRIMARY KEY (");
foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append(")"); sb.Remove(sb.Length - 2, 2).Append("),");
} }
foreach (var uk in tb.Uniques) {
sb.Append(" \r\n UNIQUE KEY ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("(");
foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append("),");
}
sb.Remove(sb.Length - 1, 1);
sb.Append("\r\n) Engine=InnoDB CHARACTER SET utf8;\r\n"); sb.Append("\r\n) Engine=InnoDB CHARACTER SET utf8;\r\n");
sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); sb.Append("INSERT INTO ").Append(tmptablename).Append(" (");
foreach (var tbcol in tb.Columns.Values) foreach (var tbcol in tb.Columns.Values)

View File

@ -274,7 +274,7 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and isnull(position
if (!loc10.TryGetValue(index_id, out loc11)) if (!loc10.TryGetValue(index_id, out loc11))
loc10.Add(index_id, loc11 = new List<DbColumnInfo>()); loc10.Add(index_id, loc11 = new List<DbColumnInfo>());
loc11.Add(loc9); loc11.Add(loc9);
if (is_unique) { if (is_unique && !is_primary_key) {
if (!uniqueColumns.TryGetValue(table_id, out loc10)) if (!uniqueColumns.TryGetValue(table_id, out loc10))
uniqueColumns.Add(table_id, loc10 = new Dictionary<string, List<DbColumnInfo>>()); uniqueColumns.Add(table_id, loc10 = new Dictionary<string, List<DbColumnInfo>>());
if (!loc10.TryGetValue(index_id, out loc11)) if (!loc10.TryGetValue(index_id, out loc11))

View File

@ -112,13 +112,17 @@ namespace FreeSql.Oracle {
sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(",");
if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true));
} }
if (tb.Primarys.Any() == false) if (tb.Primarys.Any()) {
sb.Remove(sb.Length - 1, 1);
else {
sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pk1 PRIMARY KEY ("); sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pk1 PRIMARY KEY (");
foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append(")"); sb.Remove(sb.Length - 2, 2).Append("),");
} }
foreach (var uk in tb.Uniques) {
sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE (");
foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append("),");
}
sb.Remove(sb.Length - 1, 1);
sb.Append("\r\n) \r\nLOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n"); sb.Append("\r\n) \r\nLOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n");
continue; continue;
} }
@ -185,6 +189,30 @@ where owner={{0}} and table_name={{1}}".FormatOracleSQL(tboldname ?? tbname);
} }
if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true));
} }
var dsuksql = @"
select
c.column_name,
c.constraint_name
from
all_constraints a,
all_cons_columns c
where
a.constraint_name = c.constraint_name
and a.owner = c.owner
and a.table_name = c.table_name
and a.constraint_type in ('U')
and a.owner in ({0}) and a.table_name in ({1})".FormatMySql(tboldname ?? tbname);
var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) });
foreach (var uk in tb.Uniques) {
if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue;
var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray();
if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) {
if (dsukfind1.Any()) sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append("';\r\n");
sbalter.Append("execute immediate 'ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE(");
foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sbalter.Remove(sbalter.Length - 2, 2).Append(")';\r\n");
}
}
} }
if (istmpatler == false) { if (istmpatler == false) {
sb.Append(sbalter); sb.Append(sbalter);
@ -203,13 +231,17 @@ where owner={{0}} and table_name={{1}}".FormatOracleSQL(tboldname ?? tbname);
sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(",");
if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true));
} }
if (tb.Primarys.Any() == false) if (tb.Primarys.Any()) {
sb.Remove(sb.Length - 1, 1);
else {
sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pk2 PRIMARY KEY ("); sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pk2 PRIMARY KEY (");
foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append(")"); sb.Remove(sb.Length - 2, 2).Append("),");
} }
foreach (var uk in tb.Uniques) {
sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE (");
foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append("),");
}
sb.Remove(sb.Length - 1, 1);
sb.Append("\r\n) LOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n"); sb.Append("\r\n) LOGGING \r\nNOCOMPRESS \r\nNOCACHE\r\n';\r\n");
sb.Append("execute immediate 'INSERT INTO ").Append(tmptablename).Append(" ("); sb.Append("execute immediate 'INSERT INTO ").Append(tmptablename).Append(" (");
foreach (var tbcol in tb.Columns.Values) foreach (var tbcol in tb.Columns.Values)

View File

@ -293,7 +293,7 @@ and a.owner in ({1}) and a.table_name in ({0})
if (!loc10.TryGetValue(index_id, out loc11)) if (!loc10.TryGetValue(index_id, out loc11))
loc10.Add(index_id, loc11 = new List<DbColumnInfo>()); loc10.Add(index_id, loc11 = new List<DbColumnInfo>());
loc11.Add(loc9); loc11.Add(loc9);
if (is_unique) { if (is_unique && !is_primary_key) {
if (!uniqueColumns.TryGetValue(table_id, out loc10)) if (!uniqueColumns.TryGetValue(table_id, out loc10))
uniqueColumns.Add(table_id, loc10 = new Dictionary<string, List<DbColumnInfo>>()); uniqueColumns.Add(table_id, loc10 = new Dictionary<string, List<DbColumnInfo>>());
if (!loc10.TryGetValue(index_id, out loc11)) if (!loc10.TryGetValue(index_id, out loc11))

View File

@ -155,13 +155,17 @@ namespace FreeSql.PostgreSQL {
sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(",");
if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true));
} }
if (tb.Primarys.Any() == false) if (tb.Primarys.Any()) {
sb.Remove(sb.Length - 1, 1);
else {
sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY ("); sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY (");
foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append(")"); sb.Remove(sb.Length - 2, 2).Append("),");
} }
foreach (var uk in tb.Uniques) {
sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE(");
foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append("),");
}
sb.Remove(sb.Length - 1, 1);
sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); sb.Append("\r\n) WITH (OIDS=FALSE);\r\n");
continue; continue;
} }
@ -241,6 +245,27 @@ where ns.nspname = {0} and c.relname = {1}".FormatPostgreSQL(tboldname ?? tbname
if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n"); if (tbcol.Attribute.IsNullable == false) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ALTER COLUMN ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" SET NOT NULL;\r\n");
if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true)); if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, tbcol.Attribute.IsIdentity == true));
} }
var dsuksql = @"
select
c.attname,
b.relname
from pg_index a
inner join pg_class b on b.oid = a.indexrelid
inner join pg_attribute c on c.attnum > 0 and c.attrelid = b.oid
inner join pg_namespace ns on ns.oid = b.relnamespace
inner join pg_class d on d.oid = a.indrelid
where ns.nspname in ({0}) and d.relname in ({1}) and a.indisunique = 't'".FormatMySql(tboldname ?? tbname);
var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) });
foreach (var uk in tb.Uniques) {
if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue;
var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray();
if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) {
if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n");
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE(");
foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n");
}
}
} }
if (istmpatler == false) { if (istmpatler == false) {
sb.Append(sbalter); sb.Append(sbalter);
@ -263,13 +288,17 @@ where pg_namespace.nspname={0} and pg_class.relname={1} and pg_constraint.contyp
sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(","); sb.Append(" \r\n ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ").Append(tbcol.Attribute.DbType).Append(",");
if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true)); if (tbcol.Attribute.IsIdentity == true) seqcols.Add((tbcol, tbname, true));
} }
if (tb.Primarys.Any() == false) if (tb.Primarys.Any()) {
sb.Remove(sb.Length - 1, 1);
else {
sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY ("); sb.Append(" \r\n CONSTRAINT ").Append(tbname[0]).Append("_").Append(tbname[1]).Append("_pkey PRIMARY KEY (");
foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append(")"); sb.Remove(sb.Length - 2, 2).Append("),");
} }
foreach (var uk in tb.Uniques) {
sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE(");
foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append("),");
}
sb.Remove(sb.Length - 1, 1);
sb.Append("\r\n) WITH (OIDS=FALSE);\r\n"); sb.Append("\r\n) WITH (OIDS=FALSE);\r\n");
sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); sb.Append("INSERT INTO ").Append(tmptablename).Append(" (");
foreach (var tbcol in tb.Columns.Values) foreach (var tbcol in tb.Columns.Values)

View File

@ -390,7 +390,7 @@ where ns.nspname || '.' || d.relname in ({loc8})
if (!loc10.TryGetValue(index_id, out loc11)) if (!loc10.TryGetValue(index_id, out loc11))
loc10.Add(index_id, loc11 = new List<DbColumnInfo>()); loc10.Add(index_id, loc11 = new List<DbColumnInfo>());
loc11.Add(loc9); loc11.Add(loc9);
if (is_unique) { if (is_unique && !is_primary_key) {
if (!uniqueColumns.TryGetValue(object_id, out loc10)) if (!uniqueColumns.TryGetValue(object_id, out loc10))
uniqueColumns.Add(object_id, loc10 = new Dictionary<string, List<DbColumnInfo>>()); uniqueColumns.Add(object_id, loc10 = new Dictionary<string, List<DbColumnInfo>>());
if (!loc10.TryGetValue(index_id, out loc11)) if (!loc10.TryGetValue(index_id, out loc11))

View File

@ -139,13 +139,18 @@ namespace FreeSql.SqlServer {
} }
sb.Append(","); sb.Append(",");
} }
foreach (var uk in tb.Uniques) {
sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE(");
foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append("),");
}
sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n");
continue; continue;
} }
//如果新表,旧表在一个数据库和模式下,直接修改表名 //如果新表,旧表在一个数据库和模式下,直接修改表名
if (string.Compare(tbname[0], tboldname[0], true) == 0 && if (string.Compare(tbname[0], tboldname[0], true) == 0 &&
string.Compare(tbname[1], tboldname[1], true) == 0) string.Compare(tbname[1], tboldname[1], true) == 0)
sbalter.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(_commonUtils.FormatSql(";\r\nEXEC sp_rename {0}, {1};\r\n", _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}"), _commonUtils.QuoteSqlName(tbname[2]))); sbalter.Append("use ").Append(_commonUtils.QuoteSqlName(tbname[0])).Append(_commonUtils.FormatSql(";\r\nEXEC sp_rename {0}, {1};\r\n", _commonUtils.QuoteSqlName($"{tboldname[0]}.{tboldname[1]}.{tboldname[2]}"), tbname[2]));
else { else {
//如果新表,旧表不在一起,创建新表,导入数据,删除旧表 //如果新表,旧表不在一起,创建新表,导入数据,删除旧表
istmpatler = true; istmpatler = true;
@ -207,9 +212,31 @@ use " + database, tboldname ?? tbname);
} }
sbalter.Append(";\r\n"); sbalter.Append(";\r\n");
} }
var dsuksql = string.Format(@"
use [{0}];
select
c.name
,d.name
from sys.index_columns a
inner join sys.indexes b on b.object_id = a.object_id and b.index_id = a.index_id
left join sys.columns c on c.object_id = a.object_id and c.column_id = a.column_id
left join sys.key_constraints d on d.parent_object_id = b.object_id and d.unique_index_id = b.index_id
where a.object_id in (object_id(N'[{1}].[{2}]')) and b.is_unique = 1;
use " + database, tboldname ?? tbname);
var dsuk = _orm.Ado.ExecuteArray(CommandType.Text, dsuksql).Select(a => new[] { string.Concat(a[0]), string.Concat(a[1]) });
foreach (var uk in tb.Uniques) {
if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue;
var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray();
if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) {
if (dsukfind1.Any()) sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" DROP CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(";\r\n");
sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName($"{tbname[0]}.{tbname[1]}.{tbname[2]}")).Append(" ADD CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE(");
foreach (var tbcol in uk.Value) sbalter.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sbalter.Remove(sbalter.Length - 2, 2).Append(");\r\n");
}
}
} }
if (istmpatler == false) { if (istmpatler == false) {
sb.Append(sbalter); sb.Append(sbalter).Append("\r\nuse " + database);
continue; continue;
} }
//创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名 //创建临时表,数据导进临时表,然后删除原表,将临时表改名为原表名
@ -244,6 +271,11 @@ use " + database, tboldname ?? tbname);
sb.Append(","); sb.Append(",");
idents = idents || tbcol.Attribute.IsIdentity == true; idents = idents || tbcol.Attribute.IsIdentity == true;
} }
foreach (var uk in tb.Uniques) {
sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE(");
foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append("),");
}
sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n"); sb.Remove(sb.Length - 1, 1).Append("\r\n);\r\n");
sb.Append("ALTER TABLE ").Append(tmptablename).Append(" SET (LOCK_ESCALATION = TABLE);\r\n"); 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"); if (idents) sb.Append("SET IDENTITY_INSERT ").Append(tmptablename).Append(" ON;\r\n");

View File

@ -294,7 +294,7 @@ use [{olddatabase}];
if (!loc10.TryGetValue(index_id, out loc11)) if (!loc10.TryGetValue(index_id, out loc11))
loc10.Add(index_id, loc11 = new List<DbColumnInfo>()); loc10.Add(index_id, loc11 = new List<DbColumnInfo>());
loc11.Add(loc9); loc11.Add(loc9);
if (is_unique) { if (is_unique && !is_primary_key) {
if (!uniqueColumns.TryGetValue(object_id, out loc10)) if (!uniqueColumns.TryGetValue(object_id, out loc10))
uniqueColumns.Add(object_id, loc10 = new Dictionary<string, List<DbColumnInfo>>()); uniqueColumns.Add(object_id, loc10 = new Dictionary<string, List<DbColumnInfo>>());
if (!loc10.TryGetValue(index_id, out loc11)) if (!loc10.TryGetValue(index_id, out loc11))

View File

@ -110,13 +110,17 @@ namespace FreeSql.Sqlite {
} }
sb.Append(","); sb.Append(",");
} }
if (isIndent || tb.Primarys.Any() == false) if (isIndent == false && tb.Primarys.Any()) {
sb.Remove(sb.Length - 1, 1);
else {
sb.Append(" \r\n PRIMARY KEY ("); sb.Append(" \r\n PRIMARY KEY (");
foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append(")"); sb.Remove(sb.Length - 2, 2).Append("),");
} }
foreach (var uk in tb.Uniques) {
sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE(");
foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append("),");
}
sb.Remove(sb.Length - 1, 1);
sb.Append("\r\n) \r\n;\r\n"); sb.Append("\r\n) \r\n;\r\n");
continue; continue;
} }
@ -168,6 +172,22 @@ namespace FreeSql.Sqlite {
//添加列 //添加列
istmpatler = true; istmpatler = true;
} }
var dsukMatches = _regexUK.Matches(dsql);
var dsuk = new List<string[]>();
foreach (Match dsukm in dsukMatches) {
var dbsukmg2 = dsukm.Groups[2].Value.Split(',');
if (dbsukmg2.Any() == false) continue;
foreach (var dbfield in dbsukmg2) {
dsuk.Add(new[] { Regex.Match(dbfield, @"""([^""]+)""").Groups[1].Value, dsukm.Groups[1].Value });
}
}
foreach (var uk in tb.Uniques) {
if (string.IsNullOrEmpty(uk.Key) || uk.Value.Any() == false) continue;
var dsukfind1 = dsuk.Where(a => string.Compare(a[1], uk.Key, true) == 0).ToArray();
if (dsukfind1.Any() == false || dsukfind1.Length != uk.Value.Count || dsukfind1.Where(a => uk.Value.Where(b => string.Compare(b.Attribute.Name, a[0], true) == 0).Any()).Count() != uk.Value.Count) {
istmpatler = true;
}
}
} }
if (istmpatler == false) { if (istmpatler == false) {
sb.Append(sbalter); sb.Append(sbalter);
@ -190,13 +210,17 @@ namespace FreeSql.Sqlite {
} }
sb.Append(","); sb.Append(",");
} }
if (isIndent || tb.Primarys.Any() == false) if (isIndent == false && tb.Primarys.Any()) {
sb.Remove(sb.Length - 1, 1);
else {
sb.Append(" \r\n PRIMARY KEY ("); sb.Append(" \r\n PRIMARY KEY (");
foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", "); foreach (var tbcol in tb.Primarys) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append(")"); sb.Remove(sb.Length - 2, 2).Append(")");
} }
foreach (var uk in tb.Uniques) {
sb.Append(" \r\n CONSTRAINT ").Append(_commonUtils.QuoteSqlName(uk.Key)).Append(" UNIQUE(");
foreach (var tbcol in uk.Value) sb.Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(", ");
sb.Remove(sb.Length - 2, 2).Append("),");
}
sb.Remove(sb.Length - 1, 1);
sb.Append("\r\n) \r\n;\r\n"); sb.Append("\r\n) \r\n;\r\n");
sb.Append("INSERT INTO ").Append(tmptablename).Append(" ("); sb.Append("INSERT INTO ").Append(tmptablename).Append(" (");
foreach (var tbcol in tb.Columns.Values) foreach (var tbcol in tb.Columns.Values)
@ -223,6 +247,7 @@ namespace FreeSql.Sqlite {
} }
return sb.Length == 0 ? null : sb.ToString(); return sb.Length == 0 ? null : sb.ToString();
} }
static Regex _regexUK = new Regex(@"CONSTRAINT\s*""([^""]+)""\s*UNIQUE\s*\(([^\)]+)\)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
static object syncStructureLock = new object(); static object syncStructureLock = new object();
ConcurrentDictionary<string, bool> dicSyced = new ConcurrentDictionary<string, bool>(); ConcurrentDictionary<string, bool> dicSyced = new ConcurrentDictionary<string, bool>();