Beispiel #1
0
        private List <DbForeignKey> GetForeignKeys(DatabaseConnectionInfo connectionInfo)
        {
            var fKeys = new Dictionary <string, DbForeignKey>();

            var sql         = @"select	SCHEMA_NAME(sof.schema_id) + '.' + sof.name as ConstraintName ,
        SCHEMA_NAME(sof.schema_id) as SchemaName ,
		sof.name,
		SCHEMA_NAME(sop.schema_id) + '.' + sop.name as ForeignKeyTable, 
		SCHEMA_NAME(sor.schema_id) + '.' +sor.name  as PrimaryKeyTable, 
		scp.name as ForeignKeyColumn, 
		scf.name as PrimaryKeyColumn
from sys.foreign_key_columns  fk

inner join Sys.objects sop on fk.parent_object_id = sop.object_id
inner join Sys.objects sof on fk.constraint_object_id = sof.object_id
inner join Sys.objects sor on fk.referenced_object_id = sor.object_id
inner join Sys.Columns scp on fk.parent_column_id = scp.column_id and fk.parent_object_id = scp.object_id
inner join Sys.Columns scf on fk.referenced_column_id = scf.column_id and fk.referenced_object_id = scf.object_id";
            var primaryKeys = new Dictionary <string, List <string> >();

            using (var conn = new SqlConnection(connectionInfo.ConnectionString))
            {
                conn.Open();
                using (var cmd = conn.CreateCommand())
                {
                    cmd.CommandType = CommandType.Text;
                    cmd.CommandText = sql;
                    var reader              = cmd.ExecuteReader();
                    var constraintNamePos   = reader.GetOrdinal("ConstraintName");
                    var schemaNamePos       = reader.GetOrdinal("SchemaName");
                    var namePos             = reader.GetOrdinal("name");
                    var foreignKeyTablePos  = reader.GetOrdinal("ForeignKeyTable");
                    var primaryKeyTablePos  = reader.GetOrdinal("PrimaryKeyTable");
                    var foreignKeyColumnPos = reader.GetOrdinal("ForeignKeyColumn");
                    var primaryKeyColumnPos = reader.GetOrdinal("PrimaryKeyColumn");
                    while (reader.Read())
                    {
                        var          constraintName = reader.GetString(constraintNamePos);
                        DbForeignKey fKey;
                        if (!fKeys.ContainsKey(constraintName))
                        {
                            fKey = new DbForeignKey
                            {
                                ConstraintFullName = constraintName,
                                Name            = reader.GetString(namePos),
                                SchemaName      = reader.GetString(schemaNamePos),
                                ForeignKeyTable = reader.GetString(foreignKeyTablePos),
                                PrimaryKeyTable = reader.GetString(primaryKeyTablePos)
                            };
                            fKeys.Add(constraintName, fKey);
                        }
                        fKeys[constraintName].Columns.Add(new DbForeignKeyColumn
                        {
                            PrimaryKeyColumn = reader.GetString(primaryKeyColumnPos),
                            ForeignKeyColumn = reader.GetString(foreignKeyColumnPos),
                        });
                    }
                }
            }
            Dictionary <string, DbForeignKey> .ValueCollection fkList = fKeys.Values;


            foreach (var key in  fkList)
            {
                CodeBuilder cb = new CodeBuilder();
                cb.AppendLine($"alter table {key.ForeignKeyTable}");
                cb.Indent();
                cb.AppendLine($"Add constraint {key.Name}");
                cb.StartLine("foreign key(");
                cb.AppendDelimited(", ", key.Columns, c => c.ForeignKeyColumn);
                cb.Append($") references {key.PrimaryKeyTable}(");
                cb.AppendDelimited(", ", key.Columns, c => c.PrimaryKeyColumn);
                cb.EndLine(")");
                key.Definition = cb.ToString();
            }

            return(fkList.ToList());
        }
        /// <summary>
        /// Reads specified table foreign keys.
        /// </summary>
        private void ApplyTablesForeignKeys(List <DbTable> tables, SQLServerVersions sqlServer)
        {
            /*
             * sql 2005 format
             * SELECT        CONVERT(SYSNAME, DB_NAME()) AS PKTABLE_QUALIFIER, CONVERT(SYSNAME, SCHEMA_NAME(O1.schema_id)) AS PKTABLE_OWNER, CONVERT(SYSNAME,
             *                       O1.name) AS PKTABLE_NAME, CONVERT(SYSNAME, C1.name) AS PKCOLUMN_NAME, CONVERT(SYSNAME, DB_NAME()) AS FKTABLE_QUALIFIER,
             *                       CONVERT(SYSNAME, SCHEMA_NAME(O2.schema_id)) AS FKTABLE_OWNER, CONVERT(SYSNAME, O2.name) AS FKTABLE_NAME, CONVERT(SYSNAME, C2.name)
             *                       AS FKCOLUMN_NAME, CONVERT(SMALLINT, CASE OBJECTPROPERTY(F.OBJECT_ID, 'CnstIsUpdateCascade') WHEN 1 THEN 0 ELSE 1 END) AS UPDATE_RULE,
             *                       CONVERT(SMALLINT, CASE OBJECTPROPERTY(F.OBJECT_ID, 'CnstIsDeleteCascade') WHEN 1 THEN 0 ELSE 1 END) AS DELETE_RULE, CONVERT(SYSNAME,
             *                       OBJECT_NAME(F.object_id)) AS FK_NAME, CONVERT(SYSNAME, I.name) AS PK_NAME, CONVERT(SMALLINT, 7) AS DEFERRABILITY, F.delete_referential_action,
             *                       F.update_referential_action
             * FROM            sys.all_objects AS O1 INNER JOIN
             *                       sys.foreign_keys AS F INNER JOIN
             *                       sys.foreign_key_columns AS K ON K.constraint_object_id = F.object_id INNER JOIN
             *                       sys.indexes AS I ON F.referenced_object_id = I.object_id AND F.key_index_id = I.index_id ON O1.object_id = F.referenced_object_id INNER JOIN
             *                       sys.all_objects AS O2 ON F.parent_object_id = O2.object_id INNER JOIN
             *                       sys.all_columns AS C1 ON F.referenced_object_id = C1.object_id AND K.referenced_column_id = C1.column_id INNER JOIN
             *                       sys.all_columns AS C2 ON F.parent_object_id = C2.object_id AND K.parent_column_id = C2.column_id
             */

            // GENERAL command format
            string foreignKeySql = @"SELECT OBJECT_NAME(f.constid) AS 'ForeignKey', OBJECT_NAME(f.fkeyid) AS 'FKTable',
                                        c1.name AS 'FKColumnName', OBJECT_NAME(f.rkeyid) AS 'PKTable', c2.name AS 'PKColumnName' ,
                                        -1 as update_referential_action, -1 as delete_referential_action
                                    FROM sysforeignkeys AS f
                                        INNER JOIN syscolumns AS c1 ON f.fkeyid = c1.id AND f.fkey = c1.colid
                                        INNER JOIN syscolumns AS c2 ON f.rkeyid = c2.id AND f.rkey = c2.colid
                                    ORDER BY 'FKTable', c1.colid ";

            // NEW command format
            if (sqlServer > SQLServerVersions.SQL2000)
            {
                foreignKeySql =
                    @"SELECT CONVERT(SYSNAME, DB_NAME()) AS PKTABLE_QUALIFIER, CONVERT(SYSNAME, SCHEMA_NAME(O1.schema_id)) AS PKTABLE_OWNER, CONVERT(SYSNAME,
                        O1.name) AS 'PKTable', CONVERT(SYSNAME, C1.name) AS 'PKColumnName', CONVERT(SYSNAME, DB_NAME()) AS FKTABLE_QUALIFIER,
                        CONVERT(SYSNAME, SCHEMA_NAME(O2.schema_id)) AS FKTABLE_OWNER, CONVERT(SYSNAME, O2.name) AS 'FKTable', CONVERT(SYSNAME, C2.name)
                        AS 'FKColumnName', CONVERT(SMALLINT, CASE OBJECTPROPERTY(F.OBJECT_ID, 'CnstIsUpdateCascade') WHEN 1 THEN 0 ELSE 1 END) AS UPDATE_RULE,
                        CONVERT(SMALLINT, CASE OBJECTPROPERTY(F.OBJECT_ID, 'CnstIsDeleteCascade') WHEN 1 THEN 0 ELSE 1 END) AS DELETE_RULE, CONVERT(SYSNAME,
                        OBJECT_NAME(F.object_id)) AS 'ForeignKey', CONVERT(SYSNAME, I.name) AS PK_NAME, CONVERT(SMALLINT, 7) AS DEFERRABILITY, F.delete_referential_action,
                        F.update_referential_action
                    FROM            sys.all_objects AS O1 INNER JOIN
                        sys.foreign_keys AS F INNER JOIN
                        sys.foreign_key_columns AS K ON K.constraint_object_id = F.object_id INNER JOIN
                        sys.indexes AS I ON F.referenced_object_id = I.object_id AND F.key_index_id = I.index_id ON O1.object_id = F.referenced_object_id INNER JOIN
                        sys.all_objects AS O2 ON F.parent_object_id = O2.object_id INNER JOIN
                        sys.all_columns AS C1 ON F.referenced_object_id = C1.object_id AND K.referenced_column_id = C1.column_id INNER JOIN
                        sys.all_columns AS C2 ON F.parent_object_id = C2.object_id AND K.parent_column_id = C2.column_id
                    ORDER BY 'FKTable', C2.column_id";
            }

            try
            {
                using (var adapter = new SqlDataAdapter(foreignKeySql, (SqlConnection)_dbConnection))
                {
                    adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;

                    // description data table
                    using (var keysData = new DataTable())
                    {
                        // Just to avoid stupid "Failed to enable constraints" error!
                        using (var tempDs = new DataSet())
                        {
                            // Avoiding stupid "Failed to enable constraints" error!
                            tempDs.EnforceConstraints = false;
                            tempDs.Tables.Add(keysData);

                            // Get from db
                            adapter.Fill(keysData);
                        }

                        if (keysData.Rows.Count > 0)
                        {
                            foreach (DataRow keysDataRow in keysData.Rows)
                            {
                                var foreignKeyTableName = keysDataRow["FKTable"].ToString();
                                var primaryKeyTableName = keysDataRow["PKTable"].ToString();

                                var foreignKeyTable = FindTable(tables, foreignKeyTableName);
                                var primaryKeyTable = FindTable(tables, primaryKeyTableName);

                                // one-to-many foreign relation will be added
                                if (primaryKeyTable != null)
                                {
                                    // foreign key many end
                                    var manyMultiplicityKey_Local = new DbForeignKey()
                                    {
                                        ForeignKeyName    = keysDataRow["ForeignKey"].ToString(),
                                        LocalColumnName   = keysDataRow["PKColumnName"].ToString(),
                                        ForeignColumnName = keysDataRow["FKColumnName"].ToString(),
                                        ForeignTableName  = keysDataRow["FKTable"].ToString(),
                                        Multiplicity      = DbForeignKey.ForeignKeyMultiplicity.ManyToOne
                                    };
                                    // check if it is already there
                                    if (primaryKeyTable.ForeignKeys.Exists(
                                            x =>
                                            x.Multiplicity == DbForeignKey.ForeignKeyMultiplicity.ManyToOne &&
                                            x.ForeignKeyName == manyMultiplicityKey_Local.ForeignKeyName))
                                    {
                                        continue;
                                    }

                                    manyMultiplicityKey_Local.UpdateAction =
                                        ConvertSqlServerForeignKeyAction(Convert.ToInt32(keysDataRow["update_referential_action"].ToString()));
                                    manyMultiplicityKey_Local.DeleteAction =
                                        ConvertSqlServerForeignKeyAction(Convert.ToInt32(keysDataRow["delete_referential_action"].ToString()));

                                    // to the list
                                    primaryKeyTable.ForeignKeys.Add(manyMultiplicityKey_Local);

                                    // apply local column
                                    DbColumn localColumn = primaryKeyTable.FindColumnDb(manyMultiplicityKey_Local.LocalColumnName);
                                    manyMultiplicityKey_Local.LocalColumn = localColumn;
                                    if (!localColumn.PrimaryKey)
                                    {
                                        localColumn.IsReferenceKey      = true;
                                        localColumn.IsReferenceKeyTable = primaryKeyTable;
                                    }

                                    if (foreignKeyTable != null)
                                    {
                                        // foreign table of that!
                                        manyMultiplicityKey_Local.ForeignTable = foreignKeyTable;

                                        // apply foreign column
                                        DbColumn foreignColumn = foreignKeyTable.FindColumnDb(manyMultiplicityKey_Local.ForeignColumnName);
                                        manyMultiplicityKey_Local.ForeignColumn = foreignColumn;
                                    }
                                    else
                                    {
                                        manyMultiplicityKey_Local.ForeignTable  = null;
                                        manyMultiplicityKey_Local.ForeignColumn = null;
                                    }
                                }

                                // one-to-? foreign relation will be added
                                if (foreignKeyTable != null)
                                {
                                    // foreign key many end
                                    var oneMultiplicityKey_Foreign = new DbForeignKey()
                                    {
                                        ForeignKeyName    = keysDataRow["ForeignKey"].ToString(),
                                        LocalColumnName   = keysDataRow["FKColumnName"].ToString(),
                                        ForeignColumnName = keysDataRow["PKColumnName"].ToString(),
                                        ForeignTableName  = keysDataRow["PKTable"].ToString(),
                                        Multiplicity      = DbForeignKey.ForeignKeyMultiplicity.OneToMany
                                    };
                                    // check if it is already there
                                    if (foreignKeyTable.ForeignKeys.Exists(
                                            x =>
                                            x.Multiplicity == DbForeignKey.ForeignKeyMultiplicity.OneToMany &&
                                            x.ForeignKeyName == oneMultiplicityKey_Foreign.ForeignKeyName))
                                    {
                                        continue;
                                    }

                                    oneMultiplicityKey_Foreign.UpdateAction =
                                        ConvertSqlServerForeignKeyAction(Convert.ToInt32(keysDataRow["update_referential_action"].ToString()));
                                    oneMultiplicityKey_Foreign.DeleteAction =
                                        ConvertSqlServerForeignKeyAction(Convert.ToInt32(keysDataRow["delete_referential_action"].ToString()));

                                    // to the list
                                    foreignKeyTable.ForeignKeys.Add(oneMultiplicityKey_Foreign);

                                    // apply local column
                                    DbColumn localColumn = foreignKeyTable.FindColumnDb(oneMultiplicityKey_Foreign.LocalColumnName);
                                    oneMultiplicityKey_Foreign.LocalColumn = localColumn;
                                    if (!localColumn.PrimaryKey)
                                    {
                                        localColumn.IsReferenceKey      = true;
                                        localColumn.IsReferenceKeyTable = primaryKeyTable;
                                    }

                                    if (primaryKeyTable != null)
                                    {
                                        // foreign table of that!
                                        oneMultiplicityKey_Foreign.ForeignTable = primaryKeyTable;

                                        // apply foreign column
                                        DbColumn foreignColumn = primaryKeyTable.FindColumnDb(oneMultiplicityKey_Foreign.ForeignColumnName);
                                        oneMultiplicityKey_Foreign.ForeignColumn = foreignColumn;
                                    }
                                    else
                                    {
                                        oneMultiplicityKey_Foreign.ForeignTable  = null;
                                        oneMultiplicityKey_Foreign.ForeignColumn = null;
                                    }
                                }
                            }// all foreign keys

                            // look for one-to-one situation!
                        }
                    }
                }
            }
            catch
            {
                // Seems this version of SQL Server doesn't support this query!
                // don't stop here!
            }
        }
Beispiel #3
0
        /// <summary>
        /// Reads specified table foreign keys.
        /// </summary>
        private void ApplyTablesForeignKeys(List <DbTable> tables)
        {
            if (_dbConnection.State != ConnectionState.Open)
            {
                _dbConnection.Open();
            }

            // Used to get columns Sql DataType
            using (DataTable foreignKeysTable = _dbConnection.GetSchema("ForeignKeys"))
            {
                // nothing found!
                if (foreignKeysTable.Rows.Count == 0)
                {
                    return;
                }

                // find description if there is any
                foreach (var table in tables)
                {
                    // only FOREIGN KEY
                    foreignKeysTable.DefaultView.RowFilter =
                        string.Format(" CONSTRAINT_TYPE='FOREIGN KEY' AND TABLE_NAME='{0}' ", table.TableName);

                    // Fetch the rows
                    foreach (DataRowView keysData in foreignKeysTable.DefaultView)
                    {
                        // foreign key found!
                        DataRow keyRow = keysData.Row;

                        var foreignKeyTableName = keyRow["FKEY_TO_TABLE"].ToString();
                        var primaryKeyTableName = table.TableName;

                        var foreignKeyTable = FindTable(tables, foreignKeyTableName);
                        var primaryKeyTable = table;

                        if (primaryKeyTable != null)
                        {
                            // foreign key
                            var foreignKey = new DbForeignKey()
                            {
                                ForeignKeyName    = keyRow["CONSTRAINT_NAME"].ToString(),
                                LocalColumnName   = keyRow["FKEY_FROM_COLUMN"].ToString(),
                                ForeignColumnName = keyRow["FKEY_TO_COLUMN"].ToString(),
                                ForeignTableName  = keyRow["FKEY_TO_TABLE"].ToString(),
                                Multiplicity      = DbForeignKey.ForeignKeyMultiplicity.OneToMany
                            };

                            // add foreign key
                            table.ForeignKeys.Add(foreignKey);

                            // apply local column
                            DbColumn localColumn = table.FindColumnDb(foreignKey.LocalColumnName);
                            foreignKey.LocalColumn = localColumn;

                            //apply foreign table
                            DbTable foreignTable = foreignKeyTable;

                            // referenced key
                            if (!localColumn.PrimaryKey)
                            {
                                localColumn.IsReferenceKey      = true;
                                localColumn.IsReferenceKeyTable = foreignTable;
                            }

                            if (foreignTable != null)
                            {
                                foreignKey.ForeignTable = foreignTable;

                                // apply foreign column
                                DbColumn foreignColumn = foreignTable.FindColumnDb(foreignKey.ForeignColumnName);
                                foreignKey.ForeignColumn = foreignColumn;
                            }
                            else
                            {
                                foreignKey.ForeignTable  = null;
                                foreignKey.ForeignColumn = null;
                            }
                        }

                        // adding the relation to the foreign table!
                        if (foreignKeyTable != null)
                        {
                            // foreign key
                            var oneMultiplicityKey_Foreign = new DbForeignKey()
                            {
                                ForeignKeyName    = keyRow["CONSTRAINT_NAME"].ToString(),
                                LocalColumnName   = keyRow["FKEY_TO_COLUMN"].ToString(),
                                ForeignColumnName = keyRow["FKEY_FROM_COLUMN"].ToString(),
                                ForeignTableName  = primaryKeyTableName,
                                Multiplicity      = DbForeignKey.ForeignKeyMultiplicity.ManyToOne
                            };

                            // check if it is already there
                            if (foreignKeyTable.ForeignKeys.Exists(x => x.ForeignKeyName == oneMultiplicityKey_Foreign.ForeignKeyName))
                            {
                                continue;
                            }

                            // to the list
                            foreignKeyTable.ForeignKeys.Add(oneMultiplicityKey_Foreign);

                            // apply local column
                            DbColumn localColumn = foreignKeyTable.FindColumnDb(oneMultiplicityKey_Foreign.LocalColumnName);
                            oneMultiplicityKey_Foreign.LocalColumn = localColumn;
                            if (!localColumn.PrimaryKey)
                            {
                                localColumn.IsReferenceKey      = true;
                                localColumn.IsReferenceKeyTable = primaryKeyTable;
                            }

                            if (primaryKeyTable != null)
                            {
                                // foreign table of that!
                                oneMultiplicityKey_Foreign.ForeignTable = primaryKeyTable;

                                // apply foreign column
                                DbColumn foreignColumn = primaryKeyTable.FindColumnDb(oneMultiplicityKey_Foreign.ForeignColumnName);
                                oneMultiplicityKey_Foreign.ForeignColumn = foreignColumn;
                            }
                            else
                            {
                                oneMultiplicityKey_Foreign.ForeignTable  = null;
                                oneMultiplicityKey_Foreign.ForeignColumn = null;
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Reads specified table foreign keys.
        /// </summary>
        private void ApplyTablesForeignKeys(List <DbTable> tables)
        {
            if (_dbConnection.State != ConnectionState.Open)
            {
                _dbConnection.Open();
            }
            try {
                // Used to get columns Sql DataType
                const string cmd = "SELECT  A.COLUMN_NAME as UNIQUE_COLUMN_NAME,C.COLUMN_NAME as CONSTRAINT_COLUMN_NAME , B.* FROM  INFORMATION_SCHEMA.indexes A INNER JOIN  INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS B ON UNIQUE_CONSTRAINT_NAME = INDEX_NAME  inner join INFORMATION_SCHEMA.KEY_COLUMN_USAGE C ON C.CONSTRAINT_NAME=B.CONSTRAINT_NAME";

                using (var adapter = new SqlCeDataAdapter(cmd, _dbConnection.ConnectionString))
                    using (var foreignKeysTable = new DataTable()) {
                        adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
                        adapter.Fill(foreignKeysTable);

                        // nothing found!)
                        if (foreignKeysTable.Rows.Count == 0)
                        {
                            return;
                        }

                        foreach (DataRow keyRow in foreignKeysTable.Rows)
                        {
                            var foreignKeyTableName = keyRow["CONSTRAINT_TABLE_NAME"].ToString();
                            var primaryKeyTableName = keyRow["UNIQUE_CONSTRAINT_TABLE_NAME"].ToString();

                            var foreignKeyTable = FindTable(tables, foreignKeyTableName);
                            var primaryKeyTable = FindTable(tables, primaryKeyTableName);

                            // one-to-many foreign relation will be added
                            if (primaryKeyTable != null)
                            {
                                // foreign key many end
                                var manyMultiplicityKey_Local = new DbForeignKey()
                                {
                                    ForeignKeyName    = keyRow["CONSTRAINT_NAME"].ToString(),
                                    LocalColumnName   = keyRow["UNIQUE_COLUMN_NAME"].ToString(),
                                    ForeignColumnName = keyRow["CONSTRAINT_COLUMN_NAME"].ToString(),
                                    ForeignTableName  = keyRow["CONSTRAINT_TABLE_NAME"].ToString(),
                                    Multiplicity      = DbForeignKey.ForeignKeyMultiplicity.ManyToOne
                                };

                                // check if it is already there
                                if (primaryKeyTable.ForeignKeys.Exists(x => x.ForeignKeyName == manyMultiplicityKey_Local.ForeignKeyName))
                                {
                                    continue;
                                }

                                manyMultiplicityKey_Local.UpdateAction =
                                    ConvertSqlCeForeignKeyAction(keyRow["UPDATE_RULE"].ToString());
                                manyMultiplicityKey_Local.DeleteAction =
                                    ConvertSqlCeForeignKeyAction(keyRow["DELETE_RULE"].ToString());

                                // to the list
                                primaryKeyTable.ForeignKeys.Add(manyMultiplicityKey_Local);

                                // apply local column
                                DbColumn localColumn = primaryKeyTable.FindColumnDb(manyMultiplicityKey_Local.LocalColumnName);
                                manyMultiplicityKey_Local.LocalColumn = localColumn;
                                if (!localColumn.PrimaryKey)
                                {
                                    localColumn.IsReferenceKey      = true;
                                    localColumn.IsReferenceKeyTable = primaryKeyTable;
                                }

                                if (foreignKeyTable != null)
                                {
                                    // foreign table of that!
                                    manyMultiplicityKey_Local.ForeignTable = foreignKeyTable;

                                    // apply foreign column
                                    DbColumn foreignColumn = foreignKeyTable.FindColumnDb(manyMultiplicityKey_Local.ForeignColumnName);
                                    manyMultiplicityKey_Local.ForeignColumn = foreignColumn;
                                }
                                else
                                {
                                    manyMultiplicityKey_Local.ForeignTable  = null;
                                    manyMultiplicityKey_Local.ForeignColumn = null;
                                }
                            }

                            // one-to-one foreign relation will be added
                            if (foreignKeyTable != null)
                            {
                                // foreign key many end
                                var oneMultiplicityKey_Foreign = new DbForeignKey()
                                {
                                    ForeignKeyName    = keyRow["CONSTRAINT_NAME"].ToString(),
                                    LocalColumnName   = keyRow["CONSTRAINT_COLUMN_NAME"].ToString(),
                                    ForeignColumnName = keyRow["UNIQUE_COLUMN_NAME"].ToString(),
                                    ForeignTableName  = keyRow["UNIQUE_CONSTRAINT_TABLE_NAME"].ToString(),
                                    Multiplicity      = DbForeignKey.ForeignKeyMultiplicity.OneToMany
                                };

                                // check if it is already there
                                if (foreignKeyTable.ForeignKeys.Exists(x => x.ForeignKeyName == oneMultiplicityKey_Foreign.ForeignKeyName))
                                {
                                    continue;
                                }

                                oneMultiplicityKey_Foreign.UpdateAction =
                                    ConvertSqlCeForeignKeyAction(keyRow["UPDATE_RULE"].ToString());
                                oneMultiplicityKey_Foreign.DeleteAction =
                                    ConvertSqlCeForeignKeyAction(keyRow["DELETE_RULE"].ToString());

                                // to the list
                                foreignKeyTable.ForeignKeys.Add(oneMultiplicityKey_Foreign);

                                // apply local column
                                DbColumn localColumn = foreignKeyTable.FindColumnDb(oneMultiplicityKey_Foreign.LocalColumnName);
                                oneMultiplicityKey_Foreign.LocalColumn = localColumn;
                                if (!localColumn.PrimaryKey)
                                {
                                    localColumn.IsReferenceKey      = true;
                                    localColumn.IsReferenceKeyTable = primaryKeyTable;
                                }

                                if (primaryKeyTable != null)
                                {
                                    // foreign table of that!
                                    oneMultiplicityKey_Foreign.ForeignTable = primaryKeyTable;

                                    // apply foreign column
                                    DbColumn foreignColumn = primaryKeyTable.FindColumnDb(oneMultiplicityKey_Foreign.ForeignColumnName);
                                    oneMultiplicityKey_Foreign.ForeignColumn = foreignColumn;
                                }
                                else
                                {
                                    oneMultiplicityKey_Foreign.ForeignTable  = null;
                                    oneMultiplicityKey_Foreign.ForeignColumn = null;
                                }
                            }
                        } // all keys
                    }
            }
            finally {
                _dbConnection.Close();
            }
        }
        /// <summary>
        /// Reads specified table foreign keys.
        /// </summary>
        private void ApplyTablesForeignKeys(List <DbTable> tables)
        {
            if (Cache_ForeignKeys.Rows.Count == 0)
            {
                return;
            }

            // adding the foreign keys
            foreach (DataRow keysDataRow in Cache_ForeignKeys.Rows)
            {
                var foreignKeyTableName = keysDataRow["FOREIGN_KEY_TABLE_NAME"].ToString();
                var primaryKeyTableName = keysDataRow["PRIMARY_KEY_TABLE_NAME"].ToString();

                var foreignKeyConstraintName = keysDataRow["FOREIGN_KEY_CONSTRAINT_NAME"].ToString();
                var primaryKeyConstraintName = keysDataRow["PRIMARY_KEY_CONSTRAINT_NAME"].ToString();

                string foreignKeyColumnName = null;
                string primaryKeyColumnName = null;

                // read the columns info
                DataRow[] columnInfo;

                // reading foreign key column info
                columnInfo = Cache_All_Constraints.Select(string.Format("CONSTRAINT_NAME='{0}'",
                                                                        foreignKeyConstraintName));

                if (columnInfo != null && columnInfo.Length > 0)
                {
                    foreignKeyColumnName = columnInfo[0]["COLUMN_NAME"].ToString();
                }

                // reading primary key column info
                columnInfo = Cache_All_Constraints.Select(string.Format("CONSTRAINT_NAME='{0}'",
                                                                        primaryKeyConstraintName));

                if (columnInfo != null && columnInfo.Length > 0)
                {
                    primaryKeyColumnName = columnInfo[0]["COLUMN_NAME"].ToString();
                }

                // there should be column names!
                if (foreignKeyColumnName == null || primaryKeyColumnName == null)
                {
                    continue;
                }

                // find schema tables model
                var foreignKeyTable = FindTable(tables, foreignKeyTableName);
                var primaryKeyTable = FindTable(tables, primaryKeyTableName);

                // there should be tables!
                if (foreignKeyTable == null || primaryKeyTable == null)
                {
                    continue;
                }

                if (foreignKeyTable != null)
                {
                    // foreign key many end
                    var oneMultiplicityKey = new DbForeignKey()
                    {
                        ForeignKeyName    = foreignKeyConstraintName,
                        LocalColumnName   = foreignKeyColumnName,
                        ForeignColumnName = primaryKeyColumnName,
                        ForeignTableName  = primaryKeyTableName,
                        Multiplicity      = DbForeignKey.ForeignKeyMultiplicity.OneToMany
                    };

                    // check if it is already there
                    if (foreignKeyTable.ForeignKeys.Exists(x => x.ForeignKeyName == oneMultiplicityKey.ForeignKeyName))
                    {
                        continue;
                    }

                    //oneMultiplicityKey.UpdateAction =
                    //    ConvertOracleForeignKeyAction(keysDataRow["UPDATE_RULE"].ToString());
                    oneMultiplicityKey.DeleteAction =
                        ConvertOracleForeignKeyAction(keysDataRow["DELETE_RULE"].ToString());

                    // to the list
                    foreignKeyTable.ForeignKeys.Add(oneMultiplicityKey);

                    // apply local column
                    DbColumn localColumn = foreignKeyTable.FindColumnDb(oneMultiplicityKey.LocalColumnName);
                    oneMultiplicityKey.LocalColumn = localColumn;
                    if (!localColumn.PrimaryKey)
                    {
                        localColumn.IsReferenceKey      = true;
                        localColumn.IsReferenceKeyTable = primaryKeyTable;
                    }

                    if (primaryKeyTable != null)
                    {
                        // foreign table of that!
                        oneMultiplicityKey.ForeignTable = primaryKeyTable;

                        // apply foreign column
                        DbColumn foreignColumn = primaryKeyTable.FindColumnDb(oneMultiplicityKey.ForeignColumnName);
                        oneMultiplicityKey.ForeignColumn = foreignColumn;
                    }
                    else
                    {
                        oneMultiplicityKey.ForeignTable  = null;
                        oneMultiplicityKey.ForeignColumn = null;
                    }
                }

                if (primaryKeyTable != null)
                {
                    // foreign key many end
                    var manyMultiplicityKey = new DbForeignKey()
                    {
                        ForeignKeyName    = primaryKeyConstraintName,
                        LocalColumnName   = primaryKeyColumnName,
                        ForeignColumnName = foreignKeyColumnName,
                        ForeignTableName  = foreignKeyTableName,
                        Multiplicity      = DbForeignKey.ForeignKeyMultiplicity.ManyToOne
                    };

                    // check if it is already there
                    if (primaryKeyTable.ForeignKeys.Exists(x => x.ForeignKeyName == manyMultiplicityKey.ForeignKeyName))
                    {
                        continue;
                    }

                    //manyMultiplicityKey.UpdateAction =
                    //    ConvertOracleForeignKeyAction(keysDataRow["UPDATE_RULE"].ToString());
                    manyMultiplicityKey.DeleteAction =
                        ConvertOracleForeignKeyAction(keysDataRow["DELETE_RULE"].ToString());

                    // to the list
                    primaryKeyTable.ForeignKeys.Add(manyMultiplicityKey);

                    // apply local column
                    DbColumn localColumn = primaryKeyTable.FindColumnDb(manyMultiplicityKey.LocalColumnName);
                    manyMultiplicityKey.LocalColumn = localColumn;
                    if (!localColumn.PrimaryKey)
                    {
                        localColumn.IsReferenceKey      = true;
                        localColumn.IsReferenceKeyTable = primaryKeyTable;
                    }

                    if (foreignKeyTable != null)
                    {
                        // foreign table of that!
                        manyMultiplicityKey.ForeignTable = foreignKeyTable;

                        // apply foreign column
                        DbColumn foreignColumn = foreignKeyTable.FindColumnDb(manyMultiplicityKey.ForeignColumnName);
                        manyMultiplicityKey.ForeignColumn = foreignColumn;
                    }
                    else
                    {
                        manyMultiplicityKey.ForeignTable  = null;
                        manyMultiplicityKey.ForeignColumn = null;
                    }
                }
            }
        }
        /// <summary>
        /// Applies project settings to fields name
        /// </summary>
        private string NaturalizeNames_ForeignTableFieldName(DbTable table, DbForeignKey foreignKey)
        {
            if (string.IsNullOrEmpty(foreignKey.ForeignTableNameInLocalTable))
            {
                return(foreignKey.ForeignTableNameInLocalTable);
            }
            var newName = NaturalizeNames_TableName_Rename(foreignKey.ForeignTableNameInLocalTable);

            var stringCompare = StringComparison.InvariantCulture;

            if (_patternProject.LanguageSettings.KeywordsCaseSensitive == false)
            {
                stringCompare = StringComparison.InvariantCultureIgnoreCase;
            }

            // suppress pattern
            string replacement = _patternProject.LanguageSettings.LanguageKeywordsSuppress;

            int    initReplacePartCount = 0;
            string initReplacePartStr   = "";

            // column name should not be the same
            if (newName.Equals(table.TableNameSchema, stringCompare) ||
                newName.Equals(table.TableNameSchemaCS, stringCompare))
            {
                var renamedName = string.Format(replacement, newName, initReplacePartStr);
                initReplacePartCount++;
                initReplacePartStr = initReplacePartCount.ToString();

                // no duplicate
                while (table.FindColumnSchema(renamedName) != null ||
                       table.ForeignKeys.Any(x => x.ForeignTableNameInLocalTable.Equals(renamedName, stringCompare)))
                {
                    renamedName = string.Format(replacement, newName, initReplacePartStr);
                    initReplacePartCount++;
                    initReplacePartStr = initReplacePartCount.ToString();
                }
                newName = renamedName;
            }

            // foreign name is not changed and is a member
            if (newName.Equals(foreignKey.ForeignTableNameInLocalTable, stringCompare))
            {
                var sameNameForeignKeys =
                    table.ForeignKeys.Where(x => x.ForeignTableNameInLocalTable.Equals(newName, stringCompare)).ToList();

                // no more than one occurrence, including itself
                if (table.FindColumnSchema(newName) != null ||
                    (sameNameForeignKeys.Count > 1 && sameNameForeignKeys.IndexOf(foreignKey) > 0))
                {
                    var renamedName = string.Format(replacement, newName, initReplacePartStr);
                    initReplacePartCount++;
                    initReplacePartStr = initReplacePartCount.ToString();

                    // no duplicate
                    while (table.FindColumnSchema(renamedName) != null ||
                           table.ForeignKeys.Any(x => x.ForeignTableNameInLocalTable.Equals(renamedName, stringCompare)))
                    {
                        renamedName = string.Format(replacement, newName, initReplacePartStr);
                        initReplacePartCount++;
                        initReplacePartStr = initReplacePartCount.ToString();
                    }
                    newName = renamedName;
                }
            }
            else
            {
                if (table.FindColumnSchema(newName) != null ||
                    table.ForeignKeys.Any(x => x.ForeignTableNameInLocalTable.Equals(newName, stringCompare)))
                {
                    var renamedName = string.Format(replacement, newName, initReplacePartStr);
                    initReplacePartCount++;
                    initReplacePartStr = initReplacePartCount.ToString();

                    // no duplicate
                    while (table.FindColumnSchema(renamedName) != null ||
                           table.ForeignKeys.Any(x => x.ForeignTableNameInLocalTable.Equals(renamedName, stringCompare)))
                    {
                        renamedName = string.Format(replacement, newName, initReplacePartStr);
                        initReplacePartCount++;
                        initReplacePartStr = initReplacePartCount.ToString();
                    }
                    newName = renamedName;
                }
            }

            // checking keyword match if only foreign name is not changed
            if (newName.Equals(foreignKey.ForeignTableNameInLocalTable, stringCompare))
            {
                // ignoring keywords
                foreach (var keyword in _patternProject.LanguageSettings.LanguageKeywords)
                {
                    // keyword match
                    if (newName.Equals(keyword, stringCompare))
                    {
                        var renamedName = string.Format(replacement, newName, initReplacePartStr);
                        initReplacePartCount++;
                        initReplacePartStr = initReplacePartCount.ToString();

                        // no duplicate
                        while (table.FindColumnSchema(renamedName) != null ||
                               table.ForeignKeys.Any(x => x.ForeignTableNameInLocalTable.Equals(renamedName, stringCompare)))
                        {
                            renamedName = string.Format(replacement, newName, initReplacePartStr);
                            initReplacePartCount++;
                            initReplacePartStr = initReplacePartCount.ToString();
                        }

                        newName = renamedName;
                        // name is chaned and check is no longer required
                        break;
                    }
                }
            }

            // foreign name is ok to be used
            return(newName);
        }
Beispiel #7
0
        /// <summary>
        /// Reads specified table foreign keys.
        /// </summary>
        private void ApplyTablesForeignKeys(List <DbTable> tables)
        {
            // GENERAL command format
            const string foreignKeySql = @"select 
INFORMATION_SCHEMA.KEY_COLUMN_USAGE.CONSTRAINT_NAME AS ForeignKey, 
INFORMATION_SCHEMA.KEY_COLUMN_USAGE.TABLE_NAME AS FKTable, 
INFORMATION_SCHEMA.KEY_COLUMN_USAGE.COLUMN_Name as FKColumnName, 
INFORMATION_SCHEMA.KEY_COLUMN_USAGE.REFERENCED_TABLE_NAME AS PKTable, 
INFORMATION_SCHEMA.KEY_COLUMN_USAGE.REFERENCED_COLUMN_NAME AS PKColumnName,
INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS.UPDATE_RULE AS UPDATE_RULE,
INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS.DELETE_RULE AS DELETE_RULE
from INFORMATION_SCHEMA.KEY_COLUMN_USAGE
inner join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS 
ON INFORMATION_SCHEMA.KEY_COLUMN_USAGE.CONSTRAINT_SCHEMA = INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS.CONSTRAINT_SCHEMA 
and INFORMATION_SCHEMA.KEY_COLUMN_USAGE.CONSTRAINT_NAME = INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS.CONSTRAINT_NAME 
where INFORMATION_SCHEMA.KEY_COLUMN_USAGE.constraint_SCHEMA = DATABASE()";

            try
            {
                using (var adapter = new MySqlDataAdapter(foreignKeySql, _dbConnection))
                {
                    adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;

                    // description data table
                    using (var keysData = new DataTable())
                    {
                        // Just to avoid stupid "Failed to enable constraints" error!
                        using (var tempDs = new DataSet())
                        {
                            // Avoiding stupid "Failed to enable constraints" error!
                            tempDs.EnforceConstraints = false;
                            tempDs.Tables.Add(keysData);

                            // Get from db
                            adapter.Fill(keysData);
                        }

                        if (keysData.Rows.Count > 0)
                        {
                            foreach (DataRow keysDataRow in keysData.Rows)
                            {
                                var foreignKeyTableName = keysDataRow["FKTable"].ToString();
                                var primaryKeyTableName = keysDataRow["PKTable"].ToString();

                                var foreignKeyTable = FindTable(tables, foreignKeyTableName);
                                var primaryKeyTable = FindTable(tables, primaryKeyTableName);


                                // one-to-many foreign relation will be added
                                if (primaryKeyTable != null)
                                {
                                    // foreign key many end
                                    var manyMultiplicityKeyLocal = new DbForeignKey
                                    {
                                        ForeignKeyName    = keysDataRow["ForeignKey"].ToString(),
                                        LocalColumnName   = keysDataRow["PKColumnName"].ToString(),
                                        ForeignColumnName = keysDataRow["FKColumnName"].ToString(),
                                        ForeignTableName  = keysDataRow["FKTable"].ToString(),
                                        Multiplicity      = DbForeignKey.ForeignKeyMultiplicity.ManyToOne
                                    };
                                    // check if it is already there
                                    if (primaryKeyTable.ForeignKeys.Exists(
                                            x =>
                                            x.Multiplicity == DbForeignKey.ForeignKeyMultiplicity.ManyToOne &&
                                            x.ForeignKeyName == manyMultiplicityKeyLocal.ForeignKeyName))
                                    {
                                        continue;
                                    }

                                    manyMultiplicityKeyLocal.UpdateAction =
                                        ConvertMysqlForeignKeyAction(keysDataRow["UPDATE_RULE"].ToString());
                                    manyMultiplicityKeyLocal.DeleteAction =
                                        ConvertMysqlForeignKeyAction(keysDataRow["DELETE_RULE"].ToString());

                                    // to the list
                                    primaryKeyTable.ForeignKeys.Add(manyMultiplicityKeyLocal);

                                    // apply local column
                                    var localColumn = primaryKeyTable.FindColumnDb(manyMultiplicityKeyLocal.LocalColumnName);
                                    manyMultiplicityKeyLocal.LocalColumn = localColumn;
                                    if (!localColumn.PrimaryKey)
                                    {
                                        localColumn.IsReferenceKey      = true;
                                        localColumn.IsReferenceKeyTable = primaryKeyTable;
                                    }

                                    if (foreignKeyTable != null)
                                    {
                                        // foreign table of that!
                                        manyMultiplicityKeyLocal.ForeignTable = foreignKeyTable;

                                        // apply foreign column
                                        DbColumn foreignColumn = foreignKeyTable.FindColumnDb(manyMultiplicityKeyLocal.ForeignColumnName);
                                        manyMultiplicityKeyLocal.ForeignColumn = foreignColumn;
                                    }
                                    else
                                    {
                                        manyMultiplicityKeyLocal.ForeignTable  = null;
                                        manyMultiplicityKeyLocal.ForeignColumn = null;
                                    }
                                }

                                // one-to-? foreign relation will be added
                                if (foreignKeyTable != null)
                                {
                                    // foreign key many end
                                    var oneMultiplicityKeyForeign = new DbForeignKey
                                    {
                                        ForeignKeyName    = keysDataRow["ForeignKey"].ToString(),
                                        LocalColumnName   = keysDataRow["FKColumnName"].ToString(),
                                        ForeignColumnName = keysDataRow["PKColumnName"].ToString(),
                                        ForeignTableName  = keysDataRow["PKTable"].ToString(),
                                        Multiplicity      = DbForeignKey.ForeignKeyMultiplicity.OneToMany
                                    };
                                    // check if it is already there
                                    if (foreignKeyTable.ForeignKeys.Exists(
                                            x =>
                                            x.Multiplicity == DbForeignKey.ForeignKeyMultiplicity.OneToMany &&
                                            x.ForeignKeyName == oneMultiplicityKeyForeign.ForeignKeyName))
                                    {
                                        continue;
                                    }

                                    oneMultiplicityKeyForeign.UpdateAction =
                                        ConvertMysqlForeignKeyAction(keysDataRow["UPDATE_RULE"].ToString());
                                    oneMultiplicityKeyForeign.DeleteAction =
                                        ConvertMysqlForeignKeyAction(keysDataRow["DELETE_RULE"].ToString());

                                    // to the list
                                    foreignKeyTable.ForeignKeys.Add(oneMultiplicityKeyForeign);

                                    // apply local column
                                    DbColumn localColumn = foreignKeyTable.FindColumnDb(oneMultiplicityKeyForeign.LocalColumnName);
                                    oneMultiplicityKeyForeign.LocalColumn = localColumn;
                                    if (!localColumn.PrimaryKey)
                                    {
                                        localColumn.IsReferenceKey      = true;
                                        localColumn.IsReferenceKeyTable = primaryKeyTable;
                                    }

                                    if (primaryKeyTable != null)
                                    {
                                        // foreign table of that!
                                        oneMultiplicityKeyForeign.ForeignTable = primaryKeyTable;

                                        // apply foreign column
                                        DbColumn foreignColumn = primaryKeyTable.FindColumnDb(oneMultiplicityKeyForeign.ForeignColumnName);
                                        oneMultiplicityKeyForeign.ForeignColumn = foreignColumn;
                                    }
                                    else
                                    {
                                        oneMultiplicityKeyForeign.ForeignTable  = null;
                                        oneMultiplicityKeyForeign.ForeignColumn = null;
                                    }
                                }
                            }                            // all foreign keys

                            // look for one-to-one situation!
                        }
                    }
                }
            }
            catch
            {
                // Seems this version of postgresql doesn't support this query!
                // don't stop here!
            }
        }
        /// <summary>
        /// Reads specified table foreign keys.
        /// </summary>
        private void ApplyTablesForeignKeys(List <DbTable> tables)
        {
            // GENERAL command format
            const string foreignKeySql = @"SELECT
											tc.constraint_name as ForeignKey,
											tc.table_name AS FKTable,
											kcu.column_name AS FKColumnName,
											ccu.table_name AS PKTable,
											ccu.column_name AS PKColumnName,
											-1 as update_referential_action, 
											-1 as delete_referential_action
									FROM 
											information_schema.table_constraints AS tc 
											JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name
											JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name
									WHERE constraint_type = 'FOREIGN KEY'"                                    ;

            try
            {
                using (var adapter = new NpgsqlDataAdapter(foreignKeySql, _dbConnection))
                {
                    adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;

                    // description data table
                    using (var keysData = new DataTable())
                    {
                        // Just to avoid stupid "Failed to enable constraints" error!
                        using (var tempDs = new DataSet())
                        {
                            // Avoiding stupid "Failed to enable constraints" error!
                            tempDs.EnforceConstraints = false;
                            tempDs.Tables.Add(keysData);

                            // Get from db
                            adapter.Fill(keysData);
                        }

                        if (keysData.Rows.Count > 0)
                        {
                            foreach (DataRow keysDataRow in keysData.Rows)
                            {
                                var foreignKeyTableName = keysDataRow["FKTable"].ToString();
                                var primaryKeyTableName = keysDataRow["PKTable"].ToString();

                                var foreignKeyTable = FindTable(tables, foreignKeyTableName);
                                var primaryKeyTable = FindTable(tables, primaryKeyTableName);


                                // one-to-many foreign relation will be added
                                if (primaryKeyTable != null)
                                {
                                    // foreign key many end
                                    var manyMultiplicityKeyLocal = new DbForeignKey
                                    {
                                        ForeignKeyName    = keysDataRow["ForeignKey"].ToString(),
                                        LocalColumnName   = keysDataRow["PKColumnName"].ToString(),
                                        ForeignColumnName = keysDataRow["FKColumnName"].ToString(),
                                        ForeignTableName  = keysDataRow["FKTable"].ToString(),
                                        Multiplicity      = DbForeignKey.ForeignKeyMultiplicity.ManyToOne
                                    };
                                    // check if it is already there
                                    if (primaryKeyTable.ForeignKeys.Exists(
                                            x =>
                                            x.Multiplicity == DbForeignKey.ForeignKeyMultiplicity.ManyToOne &&
                                            x.ForeignKeyName == manyMultiplicityKeyLocal.ForeignKeyName))
                                    {
                                        continue;
                                    }

                                    manyMultiplicityKeyLocal.UpdateAction =
                                        ConvertPosgresqlForeignKeyAction(Convert.ToInt32(keysDataRow["update_referential_action"].ToString()));
                                    manyMultiplicityKeyLocal.DeleteAction =
                                        ConvertPosgresqlForeignKeyAction(Convert.ToInt32(keysDataRow["delete_referential_action"].ToString()));

                                    // to the list
                                    primaryKeyTable.ForeignKeys.Add(manyMultiplicityKeyLocal);

                                    // apply local column
                                    var localColumn = primaryKeyTable.FindColumnDb(manyMultiplicityKeyLocal.LocalColumnName);
                                    manyMultiplicityKeyLocal.LocalColumn = localColumn;
                                    if (!localColumn.PrimaryKey)
                                    {
                                        localColumn.IsReferenceKey      = true;
                                        localColumn.IsReferenceKeyTable = primaryKeyTable;
                                    }

                                    if (foreignKeyTable != null)
                                    {
                                        // foreign table of that!
                                        manyMultiplicityKeyLocal.ForeignTable = foreignKeyTable;

                                        // apply foreign column
                                        DbColumn foreignColumn = foreignKeyTable.FindColumnDb(manyMultiplicityKeyLocal.ForeignColumnName);
                                        manyMultiplicityKeyLocal.ForeignColumn = foreignColumn;
                                    }
                                    else
                                    {
                                        manyMultiplicityKeyLocal.ForeignTable  = null;
                                        manyMultiplicityKeyLocal.ForeignColumn = null;
                                    }
                                }

                                // one-to-? foreign relation will be added
                                if (foreignKeyTable != null)
                                {
                                    // foreign key many end
                                    var oneMultiplicityKeyForeign = new DbForeignKey
                                    {
                                        ForeignKeyName    = keysDataRow["ForeignKey"].ToString(),
                                        LocalColumnName   = keysDataRow["FKColumnName"].ToString(),
                                        ForeignColumnName = keysDataRow["PKColumnName"].ToString(),
                                        ForeignTableName  = keysDataRow["PKTable"].ToString(),
                                        Multiplicity      = DbForeignKey.ForeignKeyMultiplicity.OneToMany
                                    };
                                    // check if it is already there
                                    if (foreignKeyTable.ForeignKeys.Exists(
                                            x =>
                                            x.Multiplicity == DbForeignKey.ForeignKeyMultiplicity.OneToMany &&
                                            x.ForeignKeyName == oneMultiplicityKeyForeign.ForeignKeyName))
                                    {
                                        continue;
                                    }

                                    oneMultiplicityKeyForeign.UpdateAction =
                                        ConvertPosgresqlForeignKeyAction(Convert.ToInt32(keysDataRow["update_referential_action"].ToString()));
                                    oneMultiplicityKeyForeign.DeleteAction =
                                        ConvertPosgresqlForeignKeyAction(Convert.ToInt32(keysDataRow["delete_referential_action"].ToString()));

                                    // to the list
                                    foreignKeyTable.ForeignKeys.Add(oneMultiplicityKeyForeign);

                                    // apply local column
                                    DbColumn localColumn = foreignKeyTable.FindColumnDb(oneMultiplicityKeyForeign.LocalColumnName);
                                    oneMultiplicityKeyForeign.LocalColumn = localColumn;
                                    if (!localColumn.PrimaryKey)
                                    {
                                        localColumn.IsReferenceKey      = true;
                                        localColumn.IsReferenceKeyTable = primaryKeyTable;
                                    }

                                    if (primaryKeyTable != null)
                                    {
                                        // foreign table of that!
                                        oneMultiplicityKeyForeign.ForeignTable = primaryKeyTable;

                                        // apply foreign column
                                        DbColumn foreignColumn = primaryKeyTable.FindColumnDb(oneMultiplicityKeyForeign.ForeignColumnName);
                                        oneMultiplicityKeyForeign.ForeignColumn = foreignColumn;
                                    }
                                    else
                                    {
                                        oneMultiplicityKeyForeign.ForeignTable  = null;
                                        oneMultiplicityKeyForeign.ForeignColumn = null;
                                    }
                                }
                            }                            // all foreign keys

                            // look for one-to-one situation!
                        }
                    }
                }
            }
            catch
            {
                // Seems this version of postgresql doesn't support this query!
                // don't stop here!
            }
        }
        private DbSchemaObject ParseSchemaObject(FileInfo file)
        {
            DbSchemaObject schemaObject = null;
            var            name         = System.IO.Path.GetFileNameWithoutExtension(file.FullName);
            var            nameparts    = name.Split('_');

            var objectType = (ESchemaObjectType)Enum.Parse(typeof(ESchemaObjectType), nameparts[0]);

            switch (objectType)
            {
            case ESchemaObjectType.Table:
                schemaObject = new DbTable();
                break;

            case ESchemaObjectType.View:
                schemaObject = new DbView();
                break;

            case ESchemaObjectType.StoredProcedure:
                schemaObject = new DbStoredProc();
                break;

            case ESchemaObjectType.ScalarFunction:
                schemaObject = new DbScalarFunction();
                break;

            case ESchemaObjectType.TableFunction:
                schemaObject = new DbTableFunction();
                break;

            case ESchemaObjectType.Trigger:
                schemaObject = new DbTrigger();
                break;

            case ESchemaObjectType.PrimaryKey:
                schemaObject = new DbPrimaryKey();
                break;

            case ESchemaObjectType.ForeignKey:
                schemaObject = new DbForeignKey();
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (schemaObject == null)
            {
                throw new Exception("Unable to identify object");
            }

            var objectParts = nameparts[1].Split('.');

            if (objectParts.Length != 2)
            {
                throw new Exception($"Problem with name {nameparts[1]}");
            }

            schemaObject.SchemaName = objectParts[0];
            schemaObject.Name       = objectParts[1];
            schemaObject.Definition = file.ReadAllText();

            return(schemaObject);
        }