예제 #1
0
        private void GetForeignKeys()
        {
            foreach (var dependentTable in _databaseModel.Tables)
            {
                var fkList = _connection.CreateCommand();
                fkList.CommandText = $"PRAGMA foreign_key_list(\"{dependentTable.Name.Replace("\"", "\"\"")}\");";

                var tableForeignKeys = new Dictionary <int, ForeignKeyModel>();

                using (var reader = fkList.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var id                 = reader.GetValueOrDefault <int>("id");
                        var fkOrdinal          = reader.GetValueOrDefault <int>("seq");
                        var principalTableName = reader.GetValueOrDefault <string>("table");

                        ForeignKeyModel foreignKey;
                        if (!tableForeignKeys.TryGetValue(id, out foreignKey))
                        {
                            TableModel principalTable;
                            _tables.TryGetValue(principalTableName, out principalTable);
                            foreignKey = new ForeignKeyModel
                            {
                                Table          = dependentTable,
                                PrincipalTable = principalTable,
                                OnDelete       = ConvertToReferentialAction(reader.GetValueOrDefault <string>("on_delete"))
                            };
                            tableForeignKeys.Add(id, foreignKey);
                        }

                        var fromColumnName = reader.GetValueOrDefault <string>("from");
                        var fkColumn       = new ForeignKeyColumnModel
                        {
                            Ordinal = fkOrdinal
                        };

                        fkColumn.Column = _tableColumns[ColumnKey(dependentTable, fromColumnName)];

                        if (foreignKey.PrincipalTable != null)
                        {
                            var         toColumnName = reader.GetValueOrDefault <string>("to");
                            ColumnModel toColumn;
                            if (!_tableColumns.TryGetValue(ColumnKey(foreignKey.PrincipalTable, toColumnName), out toColumn))
                            {
                                toColumn = new ColumnModel {
                                    Name = toColumnName
                                };
                            }
                            fkColumn.PrincipalColumn = toColumn;
                        }

                        foreignKey.Columns.Add(fkColumn);
                    }
                }

                foreach (var foreignKey in tableForeignKeys)
                {
                    dependentTable.ForeignKeys.Add(foreignKey.Value);
                }
            }
        }
예제 #2
0
        private void GetForeignKeys()
        {
            var command = _connection.CreateCommand();

            command.CommandText = @"SELECT
    schema_name(f.schema_id) AS [schema_name],
    object_name(f.parent_object_id) AS table_name,
    f.name AS foreign_key_name,
    object_schema_name(f.referenced_object_id) AS principal_table_schema_name,
    object_name(f.referenced_object_id) AS principal_table_name,
    col_name(fc.parent_object_id, fc.parent_column_id) AS constraint_column_name,
    col_name(fc.referenced_object_id, fc.referenced_column_id) AS referenced_column_name,
    is_disabled,
    delete_referential_action_desc,
    update_referential_action_desc,
    fc.constraint_column_id
FROM sys.foreign_keys AS f
    INNER JOIN sys.foreign_key_columns AS fc ON f.object_id = fc.constraint_object_id
ORDER BY schema_name(f.schema_id), object_name(f.parent_object_id), f.name";
            using (var reader = command.ExecuteReader())
            {
                var             lastFkName       = string.Empty;
                var             lastFkSchemaName = string.Empty;
                var             lastFkTableName  = string.Empty;
                ForeignKeyModel fkInfo           = null;
                while (reader.Read())
                {
                    var schemaName = reader.GetValueOrDefault <string>("schema_name");
                    var tableName  = reader.GetValueOrDefault <string>("table_name");
                    var fkName     = reader.GetValueOrDefault <string>("foreign_key_name");
                    var principalTableSchemaName = reader.GetValueOrDefault <string>("principal_table_schema_name");
                    var principalTableName       = reader.GetValueOrDefault <string>("principal_table_name");
                    var fromColumnName           = reader.GetValueOrDefault <string>("constraint_column_name");
                    var toColumnName             = reader.GetValueOrDefault <string>("referenced_column_name");
                    var updateAction             = reader.GetValueOrDefault <string>("update_referential_action_desc");
                    var deleteAction             = reader.GetValueOrDefault <string>("delete_referential_action_desc");
                    var ordinal = reader.GetValueOrDefault <int>("constraint_column_id");

                    Logger.LogDebug(
                        RelationalDesignEventId.FoundForeignKeyColumn,
                        () => SqlServerDesignStrings.FoundForeignKeyColumn(
                            schemaName, tableName, fkName, principalTableSchemaName, principalTableName,
                            fromColumnName, toColumnName, updateAction, deleteAction, ordinal));

                    if (string.IsNullOrEmpty(fkName))
                    {
                        Logger.LogWarning(
                            SqlServerDesignEventId.ForeignKeyMustBeNamedWarning,
                            () => SqlServerDesignStrings.ForeignKeyNameEmpty(schemaName, tableName));
                        continue;
                    }

                    if (!_tableSelectionSet.Allows(schemaName, tableName))
                    {
                        Logger.LogDebug(
                            SqlServerDesignEventId.ForeignKeyColumnSkipped,
                            () => SqlServerDesignStrings.ForeignKeyColumnNotInSelectionSet(
                                fromColumnName, fkName, schemaName, tableName));
                        continue;
                    }

                    if (fkInfo == null ||
                        lastFkSchemaName != schemaName ||
                        lastFkTableName != tableName ||
                        lastFkName != fkName)
                    {
                        lastFkName       = fkName;
                        lastFkSchemaName = schemaName;
                        lastFkTableName  = tableName;
                        var table = _tables[TableKey(tableName, schemaName)];

                        TableModel principalTable = null;
                        if (!string.IsNullOrEmpty(principalTableSchemaName) &&
                            !string.IsNullOrEmpty(principalTableName))
                        {
                            _tables.TryGetValue(TableKey(principalTableName, principalTableSchemaName), out principalTable);
                        }

                        if (principalTable == null)
                        {
                            Logger.LogDebug(
                                RelationalDesignEventId.ForeignKeyReferencesMissingTable,
                                () => SqlServerDesignStrings.PrincipalTableNotInSelectionSet(
                                    fkName, schemaName, tableName, principalTableSchemaName, principalTableName));
                        }

                        fkInfo = new ForeignKeyModel
                        {
                            Name           = fkName,
                            Table          = table,
                            PrincipalTable = principalTable,
                            OnDelete       = ConvertToReferentialAction(deleteAction)
                        };

                        table.ForeignKeys.Add(fkInfo);
                    }

                    var fkColumn = new ForeignKeyColumnModel
                    {
                        Ordinal = ordinal
                    };

                    ColumnModel fromColumn;
                    if ((fromColumn = FindColumnForForeignKey(fromColumnName, fkInfo.Table, fkName)) != null)
                    {
                        fkColumn.Column = fromColumn;
                    }

                    if (fkInfo.PrincipalTable != null)
                    {
                        ColumnModel toColumn;
                        if ((toColumn = FindColumnForForeignKey(toColumnName, fkInfo.PrincipalTable, fkName)) != null)
                        {
                            fkColumn.PrincipalColumn = toColumn;
                        }
                    }

                    fkInfo.Columns.Add(fkColumn);
                }
            }
        }
        private void GetForeignKeys()
        {
            var command = _connection.CreateCommand();

            command.CommandText = @"SELECT 
    schema_name(f.schema_id) AS [schema_name],
    object_name(f.parent_object_id) AS table_name,
    f.name AS foreign_key_name,
    object_schema_name(f.referenced_object_id) AS principal_table_schema_name,
    object_name(f.referenced_object_id) AS principal_table_name,
    col_name(fc.parent_object_id, fc.parent_column_id) AS constraint_column_name,
    col_name(fc.referenced_object_id, fc.referenced_column_id) AS referenced_column_name,
    is_disabled,
    delete_referential_action_desc,
    update_referential_action_desc,
    fc.constraint_column_id
FROM sys.foreign_keys AS f
    INNER JOIN sys.foreign_key_columns AS fc ON f.object_id = fc.constraint_object_id
ORDER BY schema_name(f.schema_id), object_name(f.parent_object_id), f.name";
            using (var reader = command.ExecuteReader())
            {
                var             lastFkName       = string.Empty;
                var             lastFkSchemaName = string.Empty;
                var             lastFkTableName  = string.Empty;
                ForeignKeyModel fkInfo           = null;
                while (reader.Read())
                {
                    var schemaName = reader.GetString(0);
                    var tableName  = reader.GetString(1);
                    var fkName     = reader.GetStringOrNull(2);
                    if (string.IsNullOrEmpty(fkName))
                    {
                        Logger.LogWarning(SqlServerDesignStrings.ForeignKeyNameEmpty(schemaName, tableName));
                        continue;
                    }

                    if (!_tableSelectionSet.Allows(schemaName, tableName))
                    {
                        continue;
                    }
                    if (fkInfo == null ||
                        lastFkSchemaName != schemaName ||
                        lastFkTableName != tableName ||
                        lastFkName != fkName)
                    {
                        lastFkName       = fkName;
                        lastFkSchemaName = schemaName;
                        lastFkTableName  = tableName;
                        var table = _tables[TableKey(tableName, schemaName)];

                        var        principalSchemaTableName = reader.GetStringOrNull(3);
                        var        principalTableName       = reader.GetStringOrNull(4);
                        TableModel principalTable           = null;
                        if (!string.IsNullOrEmpty(principalSchemaTableName) &&
                            !string.IsNullOrEmpty(principalTableName))
                        {
                            _tables.TryGetValue(TableKey(principalTableName, principalSchemaTableName), out principalTable);
                        }

                        fkInfo = new ForeignKeyModel
                        {
                            Name           = fkName,
                            Table          = table,
                            PrincipalTable = principalTable,
                            OnDelete       = ConvertToReferentialAction(reader.GetStringOrNull(8))
                        };

                        table.ForeignKeys.Add(fkInfo);
                    }

                    var fkColumn = new ForeignKeyColumnModel
                    {
                        Ordinal = reader.GetInt32(10)
                    };

                    var         fromColumnName = reader.GetStringOrNull(5);
                    ColumnModel fromColumn;
                    if ((fromColumn = FindColumnForForeignKey(fromColumnName, fkInfo.Table, fkName)) != null)
                    {
                        fkColumn.Column = fromColumn;
                    }

                    if (fkInfo.PrincipalTable != null)
                    {
                        var         toColumnName = reader.GetString(6);
                        ColumnModel toColumn;
                        if ((toColumn = FindColumnForForeignKey(toColumnName, fkInfo.PrincipalTable, fkName)) != null)
                        {
                            fkColumn.PrincipalColumn = toColumn;
                        }
                    }

                    fkInfo.Columns.Add(fkColumn);
                }
            }
        }
예제 #4
0
        private void GetForeignKeys()
        {
            foreach (var dependentTable in _databaseModel.Tables)
            {
                using (var fkList = _connection.CreateCommand())
                {
                    fkList.CommandText = $"PRAGMA foreign_key_list(\"{dependentTable.Name.Replace("\"", "\"\"")}\");"; // Interpolation okay; strings

                    var tableForeignKeys = new Dictionary <int, ForeignKeyModel>();

                    using (var reader = fkList.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var id = reader.GetValueOrDefault <int>("id");
                            var principalTableName = reader.GetValueOrDefault <string>("table");
                            var fromColumnName     = reader.GetValueOrDefault <string>("from");
                            var toColumnName       = reader.GetValueOrDefault <string>("to");
                            var deleteAction       = reader.GetValueOrDefault <string>("on_delete");
                            var fkOrdinal          = reader.GetValueOrDefault <int>("seq");

                            Logger.LogTrace(SqliteDesignStrings.FoundForeignKeyColumn(
                                                dependentTable.Name, id, principalTableName, fromColumnName,
                                                toColumnName, deleteAction, fkOrdinal));

                            ForeignKeyModel foreignKey;
                            if (!tableForeignKeys.TryGetValue(id, out foreignKey))
                            {
                                TableModel principalTable;
                                if (!_tables.TryGetValue(principalTableName, out principalTable))
                                {
                                    Logger.LogTrace(SqliteDesignStrings.PrincipalTableNotFound(
                                                        id, dependentTable.Name, principalTableName));
                                    continue;
                                }

                                foreignKey = new ForeignKeyModel
                                {
                                    Table          = dependentTable,
                                    PrincipalTable = principalTable,
                                    OnDelete       = ConvertToReferentialAction(deleteAction)
                                };
                            }

                            var fkColumn = new ForeignKeyColumnModel
                            {
                                Ordinal = fkOrdinal,
                                Column  = _tableColumns[ColumnKey(dependentTable, fromColumnName)]
                            };

                            ColumnModel toColumn;
                            if (!_tableColumns.TryGetValue(ColumnKey(foreignKey.PrincipalTable, toColumnName), out toColumn))
                            {
                                Logger.LogTrace(SqliteDesignStrings.PrincipalColumnNotFound(
                                                    id, dependentTable.Name, toColumnName, principalTableName));
                                continue;
                            }
                            fkColumn.PrincipalColumn = toColumn;

                            foreignKey.Columns.Add(fkColumn);

                            if (!tableForeignKeys.ContainsKey(id))
                            {
                                tableForeignKeys.Add(id, foreignKey);
                            }
                        }
                    }

                    foreach (var foreignKey in tableForeignKeys)
                    {
                        dependentTable.ForeignKeys.Add(foreignKey.Value);
                    }
                }
            }
        }
예제 #5
0
        private void GetForeignKeys()
        {
            var command = _connection.CreateCommand();
            var dbName  = _connection.Database;

            command.CommandText = $@"SELECT 
  kc.constraint_name, 
  kc.table_schema, 
  kc.table_name, 
  kc.column_name, 
  kc.referenced_table_schema, 
  kc.referenced_table_name, 
  kc.referenced_column_name, 
  kc.ordinal_position, 
  rc.update_rule, 
  rc.delete_rule 
FROM information_schema.key_column_usage as kc 
INNER JOIN information_schema.referential_constraints as rc 
ON kc.constraint_catalog = rc.constraint_catalog 
  AND kc.constraint_schema = rc.constraint_schema 
  AND kc.constraint_name = rc.constraint_name 
WHERE kc.referenced_table_name IS NOT NULL 
  AND kc.table_schema IN ({_schemaList})
  AND kc.table_name <> '{HistoryRepository.DefaultTableName}'";

            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    ForeignKeyModel fkModel               = null;
                    var             tableSchema           = reader.GetValueOrDefault <string>("table_schema");
                    var             constraintName        = reader.GetValueOrDefault <string>("constraint_name");
                    var             tableName             = reader.GetValueOrDefault <string>("table_name");
                    var             columnName            = reader.GetValueOrDefault <string>("column_name");
                    var             referencedTableSchema = reader.GetValueOrDefault <string>("referenced_table_schema");
                    var             referencedTableName   = reader.GetValueOrDefault <string>("referenced_table_name");
                    var             referencedColumnName  = reader.GetValueOrDefault <string>("referenced_column_name");
                    var             updateRule            = reader.GetValueOrDefault <string>("update_rule");
                    var             deleteRule            = reader.GetValueOrDefault <string>("delete_rule");
                    var             ordinal               = reader.GetInt32("ordinal_position");

                    if (string.IsNullOrEmpty(constraintName))
                    {
                        Logger.LogWarning("Foreign key must be named warning", tableSchema, tableName);
                        continue;
                    }

                    if (!_tableSelectionSet.Allows(tableSchema, tableName))
                    {
                        Logger.LogDebug("Foreign key column skipped", new string[] { referencedColumnName, constraintName, tableSchema, tableName });
                        continue;
                    }
                    var table = _tables[TableKey(tableName, tableSchema)];

                    TableModel principalTable = null;
                    if (!string.IsNullOrEmpty(tableSchema) &&
                        !string.IsNullOrEmpty(referencedTableName))
                    {
                        _tables.TryGetValue(TableKey(referencedTableName, tableSchema), out principalTable);
                    }

                    if (principalTable == null)
                    {
                        Logger.LogDebug("Foreign key references missing table", new string[] { constraintName, tableName, tableSchema });
                    }


                    fkModel = new ForeignKeyModel
                    {
                        Name           = constraintName,
                        Table          = table,
                        PrincipalTable = principalTable,
                        OnDelete       = ConvertToReferentialAction(deleteRule)
                    };

                    var fkColumn = new ForeignKeyColumnModel
                    {
                        Ordinal = (int)ordinal
                    };

                    ColumnModel fromColumn = FindColumnForForeignKey(columnName, fkModel.Table, constraintName);
                    if (fromColumn != null)
                    {
                        fkColumn.Column = fromColumn;
                    }

                    if (fkModel.PrincipalTable != null)
                    {
                        ColumnModel toColumn = FindColumnForForeignKey(referencedColumnName, fkModel.PrincipalTable, constraintName);
                        if (toColumn != null)
                        {
                            fkColumn.PrincipalColumn = toColumn;
                        }
                    }
                    fkModel.Columns.Add(fkColumn);
                    table.ForeignKeys.Add(fkModel);
                }
            }
        }
예제 #6
0
        private void GetForeignKeys()
        {
            var command = _connection.CreateCommand();

            command.CommandText = @"SELECT 
                KCU1.CONSTRAINT_NAME AS FK_CONSTRAINT_NAME,
                --KCU1.TABLE_NAME + '_' + KCU1.CONSTRAINT_NAME AS FK_CONSTRAINT_NAME,
                NULL AS [SCHEMA_NAME],
                KCU1.TABLE_NAME AS FK_TABLE_NAME,  
                NULL AS [UQ_SCHEMA_NAME],
                KCU2.TABLE_NAME AS UQ_TABLE_NAME, 
                KCU1.COLUMN_NAME AS FK_COLUMN_NAME, 
                KCU2.COLUMN_NAME AS UQ_COLUMN_NAME, 
                0 AS [IS_DISABLED],
                RC.DELETE_RULE, 
                RC.UPDATE_RULE,
                KCU1.ORDINAL_POSITION
                FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC 
                JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU1 ON KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME 
                AND KCU1.TABLE_NAME = RC.CONSTRAINT_TABLE_NAME 
                JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU2 ON  KCU2.CONSTRAINT_NAME =  RC.UNIQUE_CONSTRAINT_NAME 
                    AND KCU2.ORDINAL_POSITION = KCU1.ORDINAL_POSITION 
                    AND KCU2.TABLE_NAME = RC.UNIQUE_CONSTRAINT_TABLE_NAME 
                ORDER BY FK_TABLE_NAME, FK_CONSTRAINT_NAME, KCU1.ORDINAL_POSITION;";
            using (var reader = command.ExecuteReader())
            {
                var             lastFkName = "";
                ForeignKeyModel fkInfo     = null;
                while (reader.Read())
                {
                    var fkName    = reader.GetValueOrDefault <string>("FK_CONSTRAINT_NAME");
                    var tableName = reader.GetValueOrDefault <string>("FK_TABLE_NAME");

                    if (!_tableSelectionSet.Allows(tableName))
                    {
                        continue;
                    }
                    if ((fkInfo == null) ||
                        (lastFkName != fkName))
                    {
                        lastFkName = fkName;
                        var        principalTableName = reader.GetValueOrDefault <string>("UQ_TABLE_NAME");
                        var        table = _tables[TableKey(tableName)];
                        TableModel principalTable;
                        _tables.TryGetValue(TableKey(principalTableName), out principalTable);

                        fkInfo = new ForeignKeyModel
                        {
                            Name           = fkName,
                            Table          = table,
                            PrincipalTable = principalTable,
                            OnDelete       = ConvertToReferentialAction(reader.GetValueOrDefault <string>("DELETE_RULE"))
                        };

                        table.ForeignKeys.Add(fkInfo);
                    }

                    var fkColumn = new ForeignKeyColumnModel
                    {
                        Ordinal = reader.GetValueOrDefault <int>("ORDINAL_POSITION")
                    };

                    var         fromColumnName = reader.GetValueOrDefault <string>("FK_COLUMN_NAME");
                    ColumnModel fromColumn;
                    if ((fromColumn = FindColumnForForeignKey(fromColumnName, fkInfo.Table, fkName)) != null)
                    {
                        fkColumn.Column = fromColumn;
                    }

                    if (fkInfo.PrincipalTable != null)
                    {
                        var         toColumnName = reader.GetValueOrDefault <string>("UQ_COLUMN_NAME");
                        ColumnModel toColumn;
                        if ((toColumn = FindColumnForForeignKey(toColumnName, fkInfo.PrincipalTable, fkName)) != null)
                        {
                            fkColumn.PrincipalColumn = toColumn;
                        }
                    }

                    fkInfo.Columns.Add(fkColumn);
                }
            }
        }