diff --git a/FreeSql.Tests/UnitTest1.cs b/FreeSql.Tests/UnitTest1.cs index 36846f63..821b366d 100644 --- a/FreeSql.Tests/UnitTest1.cs +++ b/FreeSql.Tests/UnitTest1.cs @@ -8,6 +8,7 @@ using Newtonsoft.Json.Linq; using NpgsqlTypes; using Npgsql.LegacyPostgis; using System.Linq.Expressions; +using System.Threading.Tasks; namespace FreeSql.Tests { public class UnitTest1 { @@ -51,8 +52,51 @@ namespace FreeSql.Tests { public string srvReqstCntt { get; set; } } + public class TestEntity : EntityBase { + public int Test { get; set; } + public string Title { get; set; } + public override Task Persistent(IRepositoryUnitOfWork uof) { + uof.GetGuidRepository().Insert(this); + return Task.CompletedTask; + } + public override Task Persistent() { + var res = FreeSqlDb.Insert(this); + res.ExecuteInserted(); + return Task.CompletedTask; + } + } + public abstract class EntityBase : DomainInfrastructure { + [Column(IsPrimary = true, IsIdentity = true)] + public TKey Id { get; set; } + public Guid CompanyId { get; set; } + [Column(IsVersion = true)] + public int Version { get; set; } + } + + public abstract class DomainInfrastructure { + [Column(IsIgnore = true)] + public IFreeSql FreeSqlDb { + get { + return g.sqlite; + } + } + + + public abstract Task Persistent(IRepositoryUnitOfWork uof); + public abstract Task Persistent(); + } + [Fact] public void Test1() { + + var testddd = new TestEntity { + Test = 22, + Title = "xxx" + }; + //testddd.Persistent().Wait(); + g.sqlite.GetRepository().Insert(testddd); + + var testpid1 = g.mysql.Insert().AppendData(new TestTypeInfo { Name = "Name" + DateTime.Now.ToString("yyyyMMddHHmmss") }).ExecuteIdentity(); g.mysql.Insert().AppendData(new TestInfo { Title = "Title" + DateTime.Now.ToString("yyyyMMddHHmmss"), CreateTime = DateTime.Now, TypeGuid = (int)testpid1 }).ExecuteAffrows(); diff --git a/FreeSql/DataAnnotations/ColumnAttribute.cs b/FreeSql/DataAnnotations/ColumnAttribute.cs index 17eedaf8..c3b4d018 100644 --- a/FreeSql/DataAnnotations/ColumnAttribute.cs +++ b/FreeSql/DataAnnotations/ColumnAttribute.cs @@ -38,6 +38,10 @@ namespace FreeSql.DataAnnotations { /// public bool IsVersion { get => _IsVersion ?? false; set => _IsVersion = value; } + /// + /// 唯一键,多个属性指定相同的标识,代表联合键 + /// + public string Unique { get; set; } /// /// 数据库默认值 /// diff --git a/FreeSql/DataAnnotations/ColumnFluent.cs b/FreeSql/DataAnnotations/ColumnFluent.cs index 17cc6640..3fcd5553 100644 --- a/FreeSql/DataAnnotations/ColumnFluent.cs +++ b/FreeSql/DataAnnotations/ColumnFluent.cs @@ -65,6 +65,15 @@ namespace FreeSql.DataAnnotations { return this; } /// + /// 唯一键,多个属性指定相同的标识,代表联合键 + /// + /// 标识 + /// + public ColumnFluent Unique(string value) { + _column.Unique = value; + return this; + } + /// /// 类型映射,比如:可将 enum 属性映射成 typeof(string) /// /// diff --git a/FreeSql/DatabaseModel/DBTableInfo.cs b/FreeSql/DatabaseModel/DBTableInfo.cs index 3176bc6f..4fc8ddfc 100644 --- a/FreeSql/DatabaseModel/DBTableInfo.cs +++ b/FreeSql/DatabaseModel/DBTableInfo.cs @@ -37,15 +37,19 @@ namespace FreeSql.DatabaseModel { /// /// 唯一键/组合 /// - public List> Uniques { get; internal set; } = new List>(); + public Dictionary> UniquesDict { get; internal set; } = new Dictionary>(); /// /// 索引/组合 /// - public List> Indexes { get; internal set; } = new List>(); + public Dictionary> IndexesDict { get; internal set; } = new Dictionary>(); /// /// 外键 /// - public List Foreigns { get; internal set; } = new List(); + public Dictionary ForeignsDict { get; internal set; } = new Dictionary(); + + public IEnumerable> Uniques => UniquesDict.Values; + public IEnumerable> Indexes => IndexesDict.Values; + public IEnumerable Foreigns => ForeignsDict.Values; } public enum DbTableType { diff --git a/FreeSql/Extensions/EntityUtilExtensions.cs b/FreeSql/Extensions/EntityUtilExtensions.cs index f2ea5bd4..66f769bf 100644 --- a/FreeSql/Extensions/EntityUtilExtensions.cs +++ b/FreeSql/Extensions/EntityUtilExtensions.cs @@ -264,6 +264,7 @@ namespace FreeSql.Extensions.EntityUtil { Expression.Assign(var2Parm, Expression.TypeAs(parm2, t)) }); foreach (var prop in _table.Properties.Values) { + if (_table.ColumnsByCsIgnore.ContainsKey(prop.Name)) continue; if (_table.ColumnsByCs.ContainsKey(prop.Name)) { exps.Add( Expression.Assign( @@ -271,7 +272,7 @@ namespace FreeSql.Extensions.EntityUtil { Expression.MakeMemberAccess(var1Parm, prop) ) ); - } else { + } else if (prop.GetSetMethod() != null) { exps.Add( Expression.Assign( Expression.MakeMemberAccess(var2Parm, prop), diff --git a/FreeSql/Internal/Model/TableInfo.cs b/FreeSql/Internal/Model/TableInfo.cs index 1b99d8b1..adaa0678 100644 --- a/FreeSql/Internal/Model/TableInfo.cs +++ b/FreeSql/Internal/Model/TableInfo.cs @@ -13,6 +13,7 @@ namespace FreeSql.Internal.Model { public Dictionary ColumnsByCs { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); public Dictionary ColumnsByCsIgnore { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); public ColumnInfo[] Primarys { get; set; } + public Dictionary> Uniques { get; set; } public string CsName { get; set; } public string DbName { get; set; } public string DbOldName { get; set; } diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 3c63aecd..227bc3fd 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -77,7 +77,7 @@ namespace FreeSql.Internal { IsIgnore = false, MapType = p.PropertyType }; - if (colattr._IsNullable == null) colattr._IsNullable = tp.Value.isnullable; + if (colattr._IsNullable == null) colattr._IsNullable = tp?.isnullable; if (string.IsNullOrEmpty(colattr.DbType)) colattr.DbType = tp?.dbtypeFull ?? "varchar(255)"; colattr.DbType = colattr.DbType.ToUpper(); @@ -164,11 +164,21 @@ namespace FreeSql.Internal { trycol.Attribute.IsPrimary = true; } } + foreach(var dbuk in dbtb.UniquesDict) { + foreach (var dbcol in dbuk.Value) { + if (trytb.Columns.TryGetValue(dbcol.Name, out var trycol) && trycol.Attribute.MapType == dbcol.CsType || + trytb.ColumnsByCs.TryGetValue(dbcol.Name, out trycol) && trycol.Attribute.MapType == dbcol.CsType) { + trycol.Attribute.Unique = dbuk.Key; + } + } + } } } } catch { } trytb.Primarys = trytb.Columns.Values.Where(a => a.Attribute.IsPrimary == true).ToArray(); } + trytb.Uniques = trytb.Columns.Values.Where(a => !string.IsNullOrEmpty(a.Attribute.Unique)) + .ToDictionary(a => a.Attribute.Unique, a => trytb.Columns.Values.Where(b => b.Attribute.Unique == a.Attribute.Unique).ToList()); tbc.AddOrUpdate(entity, trytb, (oldkey, oldval) => trytb); #region 查找导航属性的关系、virtual 属性延时加载,动态产生新的重写类 diff --git a/FreeSql/MySql/MySqlDbFirst.cs b/FreeSql/MySql/MySqlDbFirst.cs index 9c62ba65..78be1d8a 100644 --- a/FreeSql/MySql/MySqlDbFirst.cs +++ b/FreeSql/MySql/MySqlDbFirst.cs @@ -239,9 +239,9 @@ where a.table_schema in ({1}) and a.table_name in ({0}) select concat(a.constraint_schema, '.', a.table_name) 'table_id', a.column_name, -concat(a.constraint_schema, '/', a.table_name, '/', a.constraint_name) 'index_id', +a.constraint_name 'index_id', 1 'IsUnique', -case when constraint_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey', +case when a.constraint_name = 'PRIMARY' then 1 else 0 end 'IsPrimaryKey', 0 'IsClustered', 0 'IsDesc' from information_schema.key_column_usage a @@ -283,13 +283,13 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and isnull(position } } foreach (string table_id in indexColumns.Keys) { - foreach (var columns in indexColumns[table_id].Values) - loc2[table_id].Indexes.Add(columns); + foreach (var column in indexColumns[table_id]) + loc2[table_id].IndexesDict.Add(column.Key, column.Value); } foreach (string table_id in uniqueColumns.Keys) { - foreach (var columns in uniqueColumns[table_id].Values) { - columns.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); - loc2[table_id].Uniques.Add(columns); + foreach (var column in uniqueColumns[table_id]) { + column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc2[table_id].UniquesDict.Add(column.Key, column.Value); } } @@ -297,7 +297,7 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and isnull(position select concat(a.constraint_schema, '.', a.table_name) 'table_id', a.column_name, -concat(a.constraint_schema, '/', a.constraint_name) 'FKId', +a.constraint_name 'FKId', concat(a.referenced_table_schema, '.', a.referenced_table_name) 'ref_table_id', 1 'IsForeignKey', a.referenced_column_name 'ref_column' @@ -335,8 +335,8 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(posi loc13.ReferencedColumns.Add(loc11); } foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id].Values) - loc2[table_id].Foreigns.Add(fk); + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); foreach (var table_id in loc3.Keys) { foreach (var loc5 in loc3[table_id].Values) { @@ -346,8 +346,8 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(posi } } foreach (var loc4 in loc2.Values) { - if (loc4.Primarys.Count == 0 && loc4.Uniques.Count > 0) { - foreach (var loc5 in loc4.Uniques[0]) { + if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) { + foreach (var loc5 in loc4.UniquesDict.First().Value) { loc5.IsPrimary = true; loc4.Primarys.Add(loc5); } @@ -356,8 +356,8 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(posi loc4.Columns.Sort((c1, c2) => { int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); if (compare == 0) { - bool b1 = loc4.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c1.Name) != null) != null; - bool b2 = loc4.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c2.Name) != null) != null; + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); compare = b2.CompareTo(b1); } if (compare == 0) compare = c1.Name.CompareTo(c2.Name); @@ -370,16 +370,6 @@ where a.constraint_schema in ({1}) and a.table_name in ({0}) and not isnull(posi if (ret == 0) ret = t1.Name.CompareTo(t2.Name); return ret; }); - foreach(var loc4 in loc1) { - var dicUniques = new Dictionary>(); - if (loc4.Primarys.Count > 0) dicUniques.Add(string.Join(",", loc4.Primarys.Select(a => a.Name)), loc4.Primarys); - foreach(var loc5 in loc4.Uniques) { - var dickey = string.Join(",", loc5.Select(a => a.Name)); - if (dicUniques.ContainsKey(dickey)) continue; - dicUniques.Add(dickey, loc5); - } - loc4.Uniques = dicUniques.Values.ToList(); - } loc2.Clear(); loc3.Clear(); diff --git a/FreeSql/Oracle/OracleDbFirst.cs b/FreeSql/Oracle/OracleDbFirst.cs index 7515ff43..41b4ed02 100644 --- a/FreeSql/Oracle/OracleDbFirst.cs +++ b/FreeSql/Oracle/OracleDbFirst.cs @@ -251,7 +251,7 @@ where a.owner in ({1}) and a.table_name in ({0}) select a.owner || '.' || a.table_name, c.column_name, -a.owner || '/' || a.table_name || '/' || c.constraint_name, +c.constraint_name, case when a.constraint_type = 'U' then 1 else 0 end, case when a.constraint_type = 'P' then 1 else 0 end, 0, @@ -302,13 +302,13 @@ and a.owner in ({1}) and a.table_name in ({0}) } } foreach (string table_id in indexColumns.Keys) { - foreach (var columns in indexColumns[table_id].Values) - loc2[table_id].Indexes.Add(columns); + foreach (var column in indexColumns[table_id]) + loc2[table_id].IndexesDict.Add(column.Key, column.Value); } foreach (string table_id in uniqueColumns.Keys) { - foreach (var columns in uniqueColumns[table_id].Values) { - columns.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); - loc2[table_id].Uniques.Add(columns); + foreach (var column in uniqueColumns[table_id]) { + column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc2[table_id].UniquesDict.Add(column.Key, column.Value); } } @@ -316,7 +316,7 @@ and a.owner in ({1}) and a.table_name in ({0}) select a.owner || '.' || a.table_name, c.column_name, -a.owner || '/' || a.table_name || '/' || c.constraint_name, +c.constraint_name, b.owner || '.' || b.table_name, 1, d.column_name @@ -379,8 +379,8 @@ and a.owner in ({1}) and a.table_name in ({0}) loc13.ReferencedColumns.Add(loc11); } foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id].Values) - loc2[table_id].Foreigns.Add(fk); + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); foreach (var table_id in loc3.Keys) { foreach (var loc5 in loc3[table_id].Values) { @@ -390,8 +390,8 @@ and a.owner in ({1}) and a.table_name in ({0}) } } foreach (var loc4 in loc2.Values) { - if (loc4.Primarys.Count == 0 && loc4.Uniques.Count > 0) { - foreach (var loc5 in loc4.Uniques[0]) { + if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) { + foreach (var loc5 in loc4.UniquesDict.First().Value) { loc5.IsPrimary = true; loc4.Primarys.Add(loc5); } @@ -400,8 +400,8 @@ and a.owner in ({1}) and a.table_name in ({0}) loc4.Columns.Sort((c1, c2) => { int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); if (compare == 0) { - bool b1 = loc4.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c1.Name) != null) != null; - bool b2 = loc4.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c2.Name) != null) != null; + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); compare = b2.CompareTo(b1); } if (compare == 0) compare = c1.Name.CompareTo(c2.Name); @@ -414,16 +414,6 @@ and a.owner in ({1}) and a.table_name in ({0}) if (ret == 0) ret = t1.Name.CompareTo(t2.Name); return ret; }); - foreach (var loc4 in loc1) { - var dicUniques = new Dictionary>(); - if (loc4.Primarys.Count > 0) dicUniques.Add(string.Join(",", loc4.Primarys.Select(a => a.Name)), loc4.Primarys); - foreach (var loc5 in loc4.Uniques) { - var dickey = string.Join(",", loc5.Select(a => a.Name)); - if (dicUniques.ContainsKey(dickey)) continue; - dicUniques.Add(dickey, loc5); - } - loc4.Uniques = dicUniques.Values.ToList(); - } loc2.Clear(); loc3.Clear(); diff --git a/FreeSql/PostgreSQL/PostgreSQLDbFirst.cs b/FreeSql/PostgreSQL/PostgreSQLDbFirst.cs index ab02131b..4b4a2930 100644 --- a/FreeSql/PostgreSQL/PostgreSQLDbFirst.cs +++ b/FreeSql/PostgreSQL/PostgreSQLDbFirst.cs @@ -343,7 +343,7 @@ where ns.nspname || '.' || c.relname in ({loc8})"; select ns.nspname || '.' || d.relname as table_id, c.attname, -ns.nspname || '/' || d.relname || '/' || b.relname as index_id, +b.relname as index_id, case when a.indisunique then 1 else 0 end IsUnique, case when a.indisprimary then 1 else 0 end IsPrimary, case when a.indisclustered then 0 else 1 end IsClustered, @@ -399,13 +399,13 @@ where ns.nspname || '.' || d.relname in ({loc8}) } } foreach (var object_id in indexColumns.Keys) { - foreach (List columns in indexColumns[object_id].Values) - loc2[object_id].Indexes.Add(columns); + foreach (var column in indexColumns[object_id]) + loc2[object_id].IndexesDict.Add(column.Key, column.Value); } foreach (var object_id in uniqueColumns.Keys) { - foreach (var columns in uniqueColumns[object_id].Values) { - columns.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); - loc2[object_id].Uniques.Add(columns); + foreach (var column in uniqueColumns[object_id]) { + column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc2[object_id].UniquesDict.Add(column.Key, column.Value); } } @@ -413,7 +413,7 @@ where ns.nspname || '.' || d.relname in ({loc8}) select ns.nspname || '.' || b.relname as table_id, array(select attname from pg_attribute where attrelid = a.conrelid and attnum = any(a.conkey)) as column_name, -a.connamespace || '/' || a.conname as FKId, +a.conname as FKId, ns2.nspname || '.' || c.relname as ref_table_id, 1 as IsForeignKey, array(select attname from pg_attribute where attrelid = a.confrelid and attnum = any(a.confkey)) as ref_column, @@ -455,8 +455,8 @@ where ns.nspname || '.' || b.relname in ({loc8}) } } foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id].Values) - loc2[table_id].Foreigns.Add(fk); + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); foreach (var table_id in loc3.Keys) { foreach (var loc5 in loc3[table_id].Values) { @@ -466,8 +466,8 @@ where ns.nspname || '.' || b.relname in ({loc8}) } } foreach (var loc4 in loc2.Values) { - if (loc4.Primarys.Count == 0 && loc4.Uniques.Count > 0) { - foreach (var loc5 in loc4.Uniques[0]) { + if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) { + foreach (var loc5 in loc4.UniquesDict.First().Value) { loc5.IsPrimary = true; loc4.Primarys.Add(loc5); } @@ -476,8 +476,8 @@ where ns.nspname || '.' || b.relname in ({loc8}) loc4.Columns.Sort((c1, c2) => { int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); if (compare == 0) { - bool b1 = loc4.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c1.Name) != null) != null; - bool b2 = loc4.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c2.Name) != null) != null; + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); compare = b2.CompareTo(b1); } if (compare == 0) compare = c1.Name.CompareTo(c2.Name); @@ -490,16 +490,6 @@ where ns.nspname || '.' || b.relname in ({loc8}) if (ret == 0) ret = t1.Name.CompareTo(t2.Name); return ret; }); - foreach (var loc4 in loc1) { - var dicUniques = new Dictionary>(); - if (loc4.Primarys.Count > 0) dicUniques.Add(string.Join(",", loc4.Primarys.Select(a => a.Name)), loc4.Primarys); - foreach (var loc5 in loc4.Uniques) { - var dickey = string.Join(",", loc5.Select(a => a.Name)); - if (dicUniques.ContainsKey(dickey)) continue; - dicUniques.Add(dickey, loc5); - } - loc4.Uniques = dicUniques.Values.ToList(); - } loc2.Clear(); loc3.Clear(); diff --git a/FreeSql/SqlServer/SqlServerDbFirst.cs b/FreeSql/SqlServer/SqlServerDbFirst.cs index 431ff098..24a721c2 100644 --- a/FreeSql/SqlServer/SqlServerDbFirst.cs +++ b/FreeSql/SqlServer/SqlServerDbFirst.cs @@ -256,7 +256,7 @@ use [{db}]; select a.object_id 'Object_id' ,c.name 'Column' -,b.index_id 'Index_id' +,d.name 'Index_id' ,b.is_unique 'IsUnique' ,b.is_primary_key 'IsPrimaryKey' ,cast(case when b.type_desc = 'CLUSTERED' then 1 else 0 end as bit) 'IsClustered' @@ -264,6 +264,7 @@ select 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 ({loc8}) ; use [{olddatabase}]; @@ -271,12 +272,12 @@ use [{olddatabase}]; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; - var indexColumns = new Dictionary>>(); - var uniqueColumns = new Dictionary>>(); + var indexColumns = new Dictionary>>(); + var uniqueColumns = new Dictionary>>(); foreach (object[] row in ds) { int object_id = int.Parse(string.Concat(row[0])); string column = string.Concat(row[1]); - int index_id = int.Parse(string.Concat(row[2])); + string index_id = string.Concat(row[2]); bool is_unique = bool.Parse(string.Concat(row[3])); bool is_primary_key = bool.Parse(string.Concat(row[4])); bool is_clustered = bool.Parse(string.Concat(row[5])); @@ -286,29 +287,29 @@ use [{olddatabase}]; DbColumnInfo loc9 = loc3[object_id][column]; if (loc9.IsPrimary == false && is_primary_key) loc9.IsPrimary = is_primary_key; - Dictionary> loc10 = null; + Dictionary> loc10 = null; List loc11 = null; if (!indexColumns.TryGetValue(object_id, out loc10)) - indexColumns.Add(object_id, loc10 = new Dictionary>()); + indexColumns.Add(object_id, loc10 = new Dictionary>()); if (!loc10.TryGetValue(index_id, out loc11)) loc10.Add(index_id, loc11 = new List()); loc11.Add(loc9); if (is_unique) { if (!uniqueColumns.TryGetValue(object_id, out loc10)) - uniqueColumns.Add(object_id, loc10 = new Dictionary>()); + uniqueColumns.Add(object_id, loc10 = new Dictionary>()); if (!loc10.TryGetValue(index_id, out loc11)) loc10.Add(index_id, loc11 = new List()); loc11.Add(loc9); } } foreach (var object_id in indexColumns.Keys) { - foreach (List columns in indexColumns[object_id].Values) - loc2[object_id].Indexes.Add(columns); + foreach (var column in indexColumns[object_id]) + loc2[object_id].IndexesDict.Add(column.Key, column.Value); } foreach (var object_id in uniqueColumns.Keys) { - foreach (var columns in uniqueColumns[object_id].Values) { - columns.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); - loc2[object_id].Uniques.Add(columns); + foreach (var column in uniqueColumns[object_id]) { + column.Value.Sort((c1, c2) => c1.Name.CompareTo(c2.Name)); + loc2[object_id].UniquesDict.Add(column.Key, column.Value); } } @@ -317,8 +318,8 @@ use [{db}]; select b.object_id 'Object_id' ,c.name 'Column' -,a.constraint_object_id 'FKId' -,referenced_object_id +,e.name 'FKId' +,a.referenced_object_id ,cast(1 as bit) 'IsForeignKey' ,d.name 'Referenced_Column' ,null 'Referenced_Sln' @@ -327,6 +328,7 @@ from sys.foreign_key_columns a inner join sys.tables b on b.object_id = a.parent_object_id inner join sys.columns c on c.object_id = a.parent_object_id and c.column_id = a.parent_column_id inner join sys.columns d on d.object_id = a.referenced_object_id and d.column_id = a.referenced_column_id +left join sys.foreign_keys e on e.object_id = a.constraint_object_id where b.object_id in ({loc8}) ; use [{olddatabase}]; @@ -334,12 +336,12 @@ use [{olddatabase}]; ds = _orm.Ado.ExecuteArray(CommandType.Text, sql); if (ds == null) return loc1; - var fkColumns = new Dictionary>(); + var fkColumns = new Dictionary>(); foreach (object[] row in ds) { - int object_id, fk_id, referenced_object_id; + int object_id, referenced_object_id; int.TryParse(string.Concat(row[0]), out object_id); var column = string.Concat(row[1]); - int.TryParse(string.Concat(row[2]), out fk_id); + string fk_id = string.Concat(row[2]); int.TryParse(string.Concat(row[3]), out referenced_object_id); var is_foreign_key = bool.Parse(string.Concat(row[4])); var referenced_column = string.Concat(row[5]); @@ -356,18 +358,18 @@ use [{olddatabase}]; } else { } - Dictionary loc12 = null; + Dictionary loc12 = null; DbForeignInfo loc13 = null; if (!fkColumns.TryGetValue(object_id, out loc12)) - fkColumns.Add(object_id, loc12 = new Dictionary()); + fkColumns.Add(object_id, loc12 = new Dictionary()); if (!loc12.TryGetValue(fk_id, out loc13)) loc12.Add(fk_id, loc13 = new DbForeignInfo { Table = loc2[object_id], ReferencedTable = loc10 }); loc13.Columns.Add(loc9); loc13.ReferencedColumns.Add(loc11); } foreach (var table_id in fkColumns.Keys) - foreach (var fk in fkColumns[table_id].Values) - loc2[table_id].Foreigns.Add(fk); + foreach (var fk in fkColumns[table_id]) + loc2[table_id].ForeignsDict.Add(fk.Key, fk.Value); foreach (var table_id in loc3.Keys) { foreach (var loc5 in loc3[table_id].Values) { @@ -377,8 +379,8 @@ use [{olddatabase}]; } } foreach (var loc4 in loc2.Values) { - if (loc4.Primarys.Count == 0 && loc4.Uniques.Count > 0) { - foreach (var loc5 in loc4.Uniques[0]) { + if (loc4.Primarys.Count == 0 && loc4.UniquesDict.Count > 0) { + foreach (var loc5 in loc4.UniquesDict.First().Value) { loc5.IsPrimary = true; loc4.Primarys.Add(loc5); } @@ -387,8 +389,8 @@ use [{olddatabase}]; loc4.Columns.Sort((c1, c2) => { int compare = c2.IsPrimary.CompareTo(c1.IsPrimary); if (compare == 0) { - bool b1 = loc4.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c1.Name) != null) != null; - bool b2 = loc4.Foreigns.Find(fk => fk.Columns.Find(c3 => c3.Name == c2.Name) != null) != null; + bool b1 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c1.Name).Any()).Any(); + bool b2 = loc4.ForeignsDict.Values.Where(fk => fk.Columns.Where(c3 => c3.Name == c2.Name).Any()).Any(); compare = b2.CompareTo(b1); } if (compare == 0) compare = c1.Name.CompareTo(c2.Name); @@ -401,16 +403,6 @@ use [{olddatabase}]; if (ret == 0) ret = t1.Name.CompareTo(t2.Name); return ret; }); - foreach (var loc4 in loc1) { - var dicUniques = new Dictionary>(); - if (loc4.Primarys.Count > 0) dicUniques.Add(string.Join(",", loc4.Primarys.Select(a => a.Name)), loc4.Primarys); - foreach (var loc5 in loc4.Uniques) { - var dickey = string.Join(",", loc5.Select(a => a.Name)); - if (dicUniques.ContainsKey(dickey)) continue; - dicUniques.Add(dickey, loc5); - } - loc4.Uniques = dicUniques.Values.ToList(); - } loc2.Clear(); loc3.Clear();