コード例 #1
0
        private void GetForeignKeys()
        {
            foreach (var dependentTable in _databaseModel.Tables)
            {
                using (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 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);
                    }
                }
            }
        }
コード例 #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.LogTrace(SqlServerDesignStrings.FoundForeignKeyColumn(
                        schemaName, tableName, fkName, principalTableSchemaName, principalTableName,
                        fromColumnName, toColumnName, updateAction, deleteAction, ordinal));

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

                    if (!_tableSelectionSet.Allows(schemaName, tableName))
                    {
                        Logger.LogTrace(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.LogTrace(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);
                }
            }
        }