private void populate_tree() { #region sql var sql = @" declare @schema_folders table (id nvarchar(200), object_name nvarchar(200), object_type nvarchar(50), parent_id nvarchar(200)) insert @schema_folders select distinct [id] = db_name() + '/SCHEMA/' + s.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS , [object_name] = o.type_desc collate SQL_Latin1_General_CP1_CI_AS , [object_type] = 'FOLDER' , [parent_id] = db_name() + '/SCHEMA/' + s.name from sys.objects o join sys.schemas s on o.schema_id = s.schema_id and o.parent_object_id = 0 where s.schema_id between 5 and 16383 ------------------------------------------------------------------------------------------------------------------------------- declare @object_folders table (id nvarchar(200), object_name nvarchar(200), object_type nvarchar(50), parent_id nvarchar(200)) insert @object_folders select distinct --constraints etc [id] = db_name() + '/SCHEMA/' + s.name + '/' + po.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + po.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS , [object_name] = o.type_desc collate SQL_Latin1_General_CP1_CI_AS , [object_type] = 'FOLDER' , [parent_id] = db_name() + '/SCHEMA/' + s.name + '/' + po.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + po.name from sys.schemas s join sys.objects o on o.schema_id = s.schema_id join sys.objects po on o.parent_object_id = po.object_id where s.schema_id between 5 and 16383 and o.parent_object_id <> 0 ------------------------------------------------------------------------------------------------------------------------------- declare @object_property_folders table (id nvarchar(200), object_name nvarchar(200), object_type nvarchar(50), parent_id nvarchar(200)) insert @object_property_folders select distinct [id] = db_name() + '/SCHEMA/' + s.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + o.name + '/PROPERTY' , [object_name] = 'PROPERTY' , [object_type] = 'FOLDER' , [parent_id] = db_name() + '/SCHEMA/' + s.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + o.name from sys.objects o join sys.schemas s on o.schema_id = s.schema_id and o.parent_object_id = 0 join sys.extended_properties ep on ep.major_id = o.object_id and ep.minor_id = 0 where s.schema_id between 5 and 16383 ------------------------------------------------------------------------------------------------------------------------------- declare @sub_object_property_folders table (id nvarchar(200), object_name nvarchar(200), object_type nvarchar(50), parent_id nvarchar(200)) insert @sub_object_property_folders select distinct --constraints etc [id] = db_name() + '/SCHEMA/' + s.name + '/' + po.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + po.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + o.name + '/PROPERTY' , [object_name] = 'PROPERTY' , [object_type] = 'FOLDER' , [parent_id] = db_name() + '/SCHEMA/' + s.name + '/' + po.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + po.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + o.name from sys.schemas s join sys.objects o on o.schema_id = s.schema_id join sys.objects po on o.parent_object_id = po.object_id join sys.extended_properties ep on ep.major_id = o.object_id and ep.class = 1 where s.schema_id between 5 and 16383 and o.parent_object_id <> 0 ------------------------------------------------------------------------------------------------------------------------------- declare @object_column_folders table (id nvarchar(200), object_name nvarchar(200), object_type nvarchar(50), parent_id nvarchar(200)) insert @object_column_folders select distinct --columns [id] = db_name() + '/SCHEMA/' + s.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + o.name + '/COLUMN' , [object_name] = 'COLUMN' , [object_type] = 'FOLDER' , [parent_id] = db_name() + '/SCHEMA/' + s.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + o.name from sys.schemas s join sys.objects o on o.schema_id = s.schema_id join sys.columns c on c.object_id = o.object_id where s.schema_id between 5 and 16383 ------------------------------------------------------------------------------------------------------------------------------- declare @object_column_property_folders table (id nvarchar(200), object_name nvarchar(200), object_type nvarchar(50), parent_id nvarchar(200)) insert @object_column_property_folders select distinct --columns [id] = db_name() + '/SCHEMA/' + s.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + o.name + '/COLUMN/' + c.name + '/PROPERTY' , [object_name] = 'PROPERTY' , [object_type] = 'FOLDER' , [parent_id] = db_name() + '/SCHEMA/' + s.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + o.name + '/COLUMN/' + c.name from sys.schemas s join sys.objects o on o.schema_id = s.schema_id join sys.columns c on c.object_id = o.object_id join sys.extended_properties ep on ep.major_id = o.object_id and ep.minor_id = c.column_id where s.schema_id between 5 and 16383 ------------------------------------------------------------------------------------------------------------------------------- select [id] = cast([id] as nvarchar(200)) , [object_name] = cast([object_name] as nvarchar(200)) , [object_type] = cast([object_type] as nvarchar(200)) , [parent_id] = cast([parent_id] as nvarchar(200)) , [definition] = cast([definition] as nvarchar(max)) from ( select --database [id] = db_name() , [object_name] = db_name() , [object_type] = 'DATABASE' collate SQL_Latin1_General_CP1_CI_AS , [parent_id] = null , [definition] = null union all select --database folders [id] = db_name() + '/SCHEMA' , [object_name] = 'SCHEMA' , [object_type] = 'FOLDER' collate SQL_Latin1_General_CP1_CI_AS , [parent_id] = db_name() , [definition] = null union all select --schemas [id] = db_name() + '/SCHEMA/' + s.name , [object_name] = s.name , [object_type] = 'SCHEMA' collate SQL_Latin1_General_CP1_CI_AS , [parent_id] = db_name() + '/SCHEMA' collate SQL_Latin1_General_CP1_CI_AS , [definition] = null from sys.schemas s where s.schema_id between 5 and 16383 union all select --schema folders *, [definition] = null from @schema_folders union all select --tables etc [id] = db_name() + '/SCHEMA/' + s.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + o.name , [object_name] = o.name , [object_type] = o.type_desc , [parent_id] = db_name() + '/SCHEMA/' + s.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS , [definition] = OBJECT_DEFINITION(o.object_id) from sys.schemas s join sys.objects o on o.schema_id = s.schema_id where s.schema_id between 5 and 16383 and o.parent_object_id = 0 union all select *, [definition] = null from @object_folders union all select *, [definition] = null from @object_column_folders union all select *, [definition] = null from @object_property_folders union all select --table properties etc [id] = db_name() + '/SCHEMA/' + s.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + o.name + '/PROPERTY/' + ep.name , [object_name] = ep.name , [object_type] = 'PROPERTY' , [parent_id] = db_name() + '/SCHEMA/' + s.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + o.name + '/PROPERTY' , [definition] = cast(ep.value as nvarchar(max)) from sys.objects o join sys.schemas s on o.schema_id = s.schema_id and o.parent_object_id = 0 join sys.extended_properties ep on ep.major_id = o.object_id and ep.minor_id = 0 where s.schema_id between 5 and 16383 union all select --constraints etc [id] = db_name() + '/SCHEMA/' + s.name + '/' + po.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + po.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + o.name , [object_name] = o.name , [object_type] = o.type_desc , [parent_id] = db_name() + '/SCHEMA/' + s.name + '/' + po.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + po.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS , [definition] = OBJECT_DEFINITION(o.object_id) from sys.schemas s join sys.objects o on o.schema_id = s.schema_id join sys.objects po on o.parent_object_id = po.object_id where s.schema_id between 5 and 16383 and o.parent_object_id <> 0 union all select --properties of constraints etc [id] = db_name() + '/SCHEMA/' + s.name + '/' + po.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + po.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + o.name + '/PROPERTY/' + ep.name , [object_name] = ep.name , [object_type] = 'PROPERTY' , [parent_id] = db_name() + '/SCHEMA/' + s.name + '/' + po.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + po.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + o.name + '/PROPERTY' , [definition] = cast(ep.value as nvarchar(max)) from sys.schemas s join sys.objects o on o.schema_id = s.schema_id join sys.objects po on o.parent_object_id = po.object_id join sys.extended_properties ep on ep.major_id = o.object_id and ep.minor_id = 0 where s.schema_id between 5 and 16383 and o.parent_object_id <> 0 union all select *, [definition] = null from @sub_object_property_folders union all select --columns [id] = db_name() + '/SCHEMA/' + s.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + o.name + '/COLUMN/' + c.name , [object_name] = c.name , [object_type] = 'COLUMN' collate SQL_Latin1_General_CP1_CI_AS , [parent_id] = db_name() + '/SCHEMA/' + s.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + o.name + '/COLUMN' , [definition] = null from sys.schemas s join sys.objects o on o.schema_id = s.schema_id join sys.columns c on c.object_id = o.object_id where s.schema_id between 5 and 16383 union all select --property folders *, [definition] = null from @object_column_property_folders union all select --columns properties [id] = db_name() + '/SCHEMA/' + s.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + o.name + '/COLUMN/' + c.name + '/PROPERTY/' + ep.name , [object_name] = ep.name , [object_type] = 'PROPERTY' collate SQL_Latin1_General_CP1_CI_AS , [parent_id] = db_name() + '/SCHEMA/' + s.name + '/' + o.type_desc collate SQL_Latin1_General_CP1_CI_AS + '/' + o.name + '/COLUMN/' + c.name + '/PROPERTY' , [definition] = cast(ep.value as nvarchar(max)) from sys.schemas s join sys.objects o on o.schema_id = s.schema_id join sys.columns c on c.object_id = o.object_id join sys.extended_properties ep on ep.major_id = o.object_id and ep.minor_id = c.column_id where s.schema_id between 5 and 16383 ) t order by id "; #endregion var conn = new DBConnection() { Server = @"pmvd\sql2012", InitialDatabase = "fe", User = "******", Password = "******" }; this.project.Connections.Add(conn); var data = conn.GetDataTable(sql); //all objects var nodes = new List <TreeNode>(); var root_node = new TreeNode(); foreach (DataRow r in data.Rows) { var id = r["id"].ToString(); var object_name = r["object_name"].ToString(); var object_type = r["object_type"].ToString(); var parent_id = r["parent_id"].ToString(); var definition = r["definition"].ToString(); DBObject db_obj = new DBObject(); switch (r["object_type"].ToString()) { case "DATABASE": db_obj = new DB(); break; case "FOLDER": db_obj = new DBFolder(); break; case "SCHEMA": db_obj = new DBSchema(); break; case "USER_TABLE": db_obj = new DBTable(); break; case "VIEW": db_obj = new DBView(); break; case "SQL_STORED_PROCEDURE": db_obj = new DBStoredProcedure(); break; case "SQL_TRIGGER": db_obj = new DBTrigger(); break; case "FOREIGN_KEY_CONSTRAINT": db_obj = new DBFKConstraint(); break; case "PRIMARY_KEY_CONSTRAINT": db_obj = new DBPKConstraint(); break; case "SQL_SCALAR_FUNCTION": db_obj = new DBFunction(); break; // case "SQL_INLINE_TABLE_VALUED_FUNCTION": db_obj = new DBFunction(); break; // case "SQL_TABLE_VALUED_FUNCTION": db_obj = new DBFunction(); break; // case "CHECK_CONSTRAINT": db_obj = new DBCheckConstraint(); break; case "UNIQUE_CONSTRAINT": db_obj = new DBUniqueConstraint(); break; case "DEFAULT_CONSTRAINT": db_obj = new DBDefaultConstraint(); break; case "COLUMN": db_obj = new DBColumn(); break; case "PROPERTY": db_obj = new DBExtendedProperty(); break; default: db_obj = null; break; } if (db_obj != null) { db_obj.PathID = id; db_obj.Name = object_name; db_obj.Connection = conn; db_obj.DefinitionSQL = definition; db_objects.Add(id, db_obj); //flat list var n = new TreeNode(db_obj.Name) { Tag = db_obj }; nodes.Add(n); if (parent_id != "") { //update parent reference in this object var parent_obj = db_objects[parent_id]; if (db_obj is DBFolder) { db_obj.Parent = parent_obj; //an object owns a folder } else { db_obj.Parent = parent_obj.Parent; //parent of the folder owns the object } //add this object as a child if (parent_obj is DBFolder) { parent_obj.Parent.DBObjects.Add(db_obj); //add it as direct child of folder owner } parent_obj.DBObjects.Add(db_obj); //folder owns automatically //set schema reference if applicable if (parent_obj.Parent != null && parent_obj.Parent is DBSchema) { (db_obj as DBSchemaObject).Schema = parent_obj.Parent as DBSchema; } //tree var parent_node = nodes.Where(x => (x.Tag as DBObject).PathID == parent_id).FirstOrDefault(); parent_node.Nodes.Add(n); } else { root_node = n; } } } //db_objects list populated. var fks = this.get_foreign_keys(); //fks //wire the foreign keys to columns foreach (var fk in fks) { var o = (db_objects[fk.Key] as DBFKConstraint); var v = fk.Value; o.CascadeLookup = v.CascadeLookup; o.Column = v.Column; o.OnDelete = v.OnDelete; o.OnUpdate = v.OnUpdate; o.ReferenceColumn = v.ReferenceColumn; o.RefreshParent = v.RefreshParent; o.RespectCreate = v.RespectCreate; o.RespectDelete = v.RespectDelete; o.RespectRead = v.RespectRead; o.RespectUpdate = v.RespectUpdate; //update sub tables collection //var sub_relations = new DBFolder { Name = "SUB_RELATION" }; //sub_relations.DBObjects.Add(o); if (!v.ReferenceColumn.Parent.DBObjects.Contains(o)) { v.ReferenceColumn.Parent.DBObjects.Add(o); } } //distribute db_objects into owner collections (properties of type list and same dbobject type) foreach (var ob in db_objects.Select(x => x.Value).ToList()) { var type = ob.GetType(); var infos = type.GetProperties(); foreach (var info in infos) { //check the type Type proptype = info.PropertyType; if (proptype.IsGenericType && (proptype.GetGenericTypeDefinition() == typeof(List <>) || proptype.GetGenericTypeDefinition() == typeof(BindingList <>) || proptype.GetGenericTypeDefinition() == typeof(MyBindingList <>))) { Type itemType = proptype.GetGenericArguments()[0]; if (typeof(DBObject).IsAssignableFrom(itemType)) //if inherits DBObject { var obj = info.GetValue(ob); var collection = new List <DBObject>(); collection.AddRange(ob.DBObjects.Where(o => o.GetType() == itemType).ToList()); var method = proptype.GetMethod("Add"); foreach (var i in collection) { if (obj != null) { method.Invoke(obj, new object[] { i }); } } } } } } treeView1.Nodes.Add(root_node); }