//Метод получения первичной информации о связях таблиц из БД private bool GetDBTablesRelations(RelationMatrix relationMatrix) { ; using (var sConn = new NpgsqlConnection(sConnStr)) { //Проверка подключения try { sConn.Open(); } catch { return(false); } //Формируем команду var sCommand = new NpgsqlCommand { Connection = sConn, CommandText = @" SELECT t1.table_name AS base_table, t1.column_name AS base_column, t2.table_name AS aim_table, t2.column_name AS aim_column FROM information_schema.key_column_usage AS t1 JOIN information_schema.constraint_column_usage AS t2 ON t1.constraint_schema = t2.constraint_schema AND t1.constraint_name = t2.constraint_name JOIN information_schema.table_constraints AS t3 ON t2.constraint_schema = t3.constraint_schema AND t2.constraint_name = t3.constraint_name WHERE t3.constraint_type = 'FOREIGN KEY' AND t1.constraint_schema = 'public' " }; //Запрос и заполнение списка using (var reader = sCommand.ExecuteReader()) { while (reader.Read()) { var baseTableName = (string)reader["base_table"]; var baseColumnName = (string)reader["base_column"]; var aimTableName = (string)reader["aim_table"]; var aimColumnName = (string)reader["aim_column"]; string connectionCondition = $"\"{baseTableName}\".\"{baseColumnName}\" = \"{aimTableName}\".\"{aimColumnName}\""; //Создаём двухстороннюю связь relationMatrix[baseTableName][aimTableName] = new RelationMatixElem { ViaTable = aimTableName, ConnectionCondition = connectionCondition }; relationMatrix[aimTableName][baseTableName] = new RelationMatixElem { ViaTable = baseTableName, ConnectionCondition = connectionCondition }; } } } return(true); }
//Метод формирования матрицы связей таблиц БД. (параметр)(матрица достижимости) public RelationMatrix GetRelationMatrix(List <TableInfo> tables) { RelationMatrix relationMatrix = new RelationMatrix(tables); //Заполним матрицу первоначальными данными. Не смогли - ошибка if (!GetDBTablesRelations(relationMatrix)) { return(null); } //Составляем список имён всех таблиц var allTableNames = new List <string>(); foreach (var table in tables) { allTableNames.Add(table.TableName); } //Заполняем матрицу foreach (var baseTableName in allTableNames) { //Получаем список соседей этой таблицы var neighborTableNames = relationMatrix.GetNeighborTablesNames(baseTableName); //Для каждого соседа ищем достижимые вершины foreach (var neighborTableName in neighborTableNames) { var reachebleTables = new HashSet <string>(); //множество достижимых из соседней таблицы таблиц reachebleTables.Add(baseTableName); //базовая таблица достижима - в неё идти не надо relationMatrix.GetConnectedTablesNames(reachebleTables, neighborTableName); reachebleTables.Remove(baseTableName); //убираем базовую таблицу из множества достижимых - здесь она нам не нужна //Помечаем достижимые из соседа вершины как достижимые из базовой таблицы, делаем в матрице соотв. запись foreach (var reachebleTableName in reachebleTables) { relationMatrix[baseTableName][reachebleTableName] = new RelationMatixElem { ViaTable = neighborTableName, ConnectionCondition = relationMatrix[baseTableName][neighborTableName].ConnectionCondition } } ; } } return(relationMatrix); }