Как получить ограничения первичного ключа столбцов с помощью SqlConnection.Метод getschema()

у меня есть код ADO.NET чтобы динамически определять схему базы данных, мне нужно получить уникальные ограничения столбцов и ограничения первичного ключа с помощью GetSchema метод on SqlConnection. Это код, который у меня есть:

conn.Open();     
SqlCommand mSqlCommand = new SqlCommand("sp_pkeys", conn);
mSqlCommand.CommandType = CommandType.StoredProcedure;
mSqlCommand.Parameters.Add(
    "@table_name", SqlDbType.NVarChar).Value = tableName;
SqlDataReader mReader = mSqlCommand.ExecuteReader(
    (CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly));
//ExecuteReader();
DataTable schema = mReader.GetSchemaTable();
mReader.Close();
conn.Close();

4 ответов


в призыве к GetSchemaTable on SqlConnection что позволит Вам разобраться в этом.

он может кажется что вы можете, используя IsKey значение столбца, которое должно возвращать true для всего, что способствует уникальной идентификации записи в таблице. Однако из документации для генерируется из базовой таблицы первичный ключ, уникальное ограничение или уникальный индекс.

из-за этого, вы не можете гарантировать, что он вносит в первичный ключ на SE.

теперь, если все, что вам нужно что-то однозначно идентифицировать строку, то IsKey отлично, так как первичный ключ не всегда является способом уникальной идентификации строки (например, вы можете иметь естественные идентификаторы с уникальным индексом). Даже если у вас есть первичный ключ и уникальный индекс с другими столбцами, значения во всех этих столбцах всегда будут уникальными.

однако, если вам конкретно нужно посмотреть столбцы, которые составляют первичный ключ, то GetSchemaTable не даст вам информацию необходимость. Скорее, вы можете просто позвонить в sp_pkeys системная хранимая процедура для поиска имен столбцов, которые способствуют созданию первичного ключа.


если кому-то еще нужны решения, я создал функцию для этого, Sqlcommand содержит инструкцию, которую вы хотите получить информацию о схеме.

Public Shared Function TableFromCommand(ByVal Command As SqlCommand) As DataTable

    Dim Cn As SqlConnection = Nothing
    Dim Dt As DataTable
    Dim Dr As SqlDataReader
    Dim Column As DataColumn
    Dim Answer As New DataTable

    Try
        Answer.TableName = "SearchTable"
        Cn = New SqlConnection("Your connection string")
        Cn.Open()

        Command.Connection = Cn
        For Each Prm As SqlParameter In Command.Parameters
            If Prm.Direction = ParameterDirection.Input _
            OrElse Prm.Direction = ParameterDirection.InputOutput Then
                Prm.Value = DBNull.Value
            End If
        Next

        Dr = Command.ExecuteReader(CommandBehavior.SchemaOnly Or CommandBehavior.KeyInfo)
        Dt = Dr.GetSchemaTable
        Dim Keys As New List(Of DataColumn)
        Dim ColumnsDic As New SortedDictionary(Of Integer, DataColumn)

        For Each Row As DataRow In Dt.Rows
            Column = New DataColumn
            With Column
                .ColumnName = Row("ColumnName").ToString
                .DataType = Type.GetType(Row("DataType").ToString)
                .AllowDBNull = CBool(Row("AllowDBNull"))
                .Unique = CBool(Row("IsUnique"))
                .ReadOnly = CBool(Row("IsReadOnly"))

                If Type.GetType(Row("DataType").ToString) Is GetType(String) Then
                    .MaxLength = CInt(Row("ColumnSize"))
                End If

                If CBool(Row("IsIdentity")) = True Then
                    .AutoIncrement = True
                    .AutoIncrementSeed = -1
                    .AutoIncrementStep = -1
                End If

                If CBool(Row("IsKey")) = True Then
                    Keys.Add(Column)
                End If
            End With

            ColumnsDic.Add(CInt(Row("ColumnOrdinal")), Column)

            Answer.Columns.Add(Column)
        Next

        If Keys.Count > 0 Then
            Answer.Constraints.Add("PrimaryKey", Keys.ToArray, True)
        End If
    Catch ex As Exception
        MyError.Show(ex)
    Finally
        If Cn IsNot Nothing AndAlso Not Cn.State = ConnectionState.Closed Then
            Cn.Close()
        End If
    End Try

    Return Answer

End Function

вы можете узнать primaryKeys, UniqueKeys и ForeignKeys и любая другая схема, перечисленная в dataTable, возвращаемая этой командой:"connection.GetSchema (" MetaDataCollections ")"

ниже кода, который возвращает вам primaryKeys и UniqueKeys (имя ключа и имя столбца).

посмотреть всю документацию здесь

    public void Dotransfer()
    {
        var sourceSchema = new TableSchema(SourceConnectionString);

    }



  public class TableSchema
    {
        public TableSchema(string connectionString)
        {
            this.TableList = new List<string>();
            this.ColumnList = new List<Columns>();
            this.PrimaryKeyList = new List<PrimaryKey>();
            this.ForeignKeyList = new List<ForeignKey>();
            this.UniqueKeyList = new List<UniqueKey>();

            GetDataBaseSchema(connectionString);

        }

        public List<string> TableList { get; set; }
        public List<Columns> ColumnList { get; set; }
        public List<PrimaryKey> PrimaryKeyList { get; set; }
        public List<UniqueKey> UniqueKeyList { get; set; }
        public List<ForeignKey> ForeignKeyList { get; set; }


        protected void GetDataBaseSchema(string ConnectionString)
        {
            using (SqlConnection connection = new SqlConnection(ConnectionString))
            {

                System.Data.SqlClient.SqlConnectionStringBuilder builder = new System.Data.SqlClient.SqlConnectionStringBuilder();
                builder.ConnectionString = ConnectionString;
                string server = builder.DataSource;
                string database = builder.InitialCatalog;

                connection.Open();


                DataTable schemaTables = connection.GetSchema("Tables");

                foreach (System.Data.DataRow rowTable in schemaTables.Rows)
                {
                    String tableName = rowTable.ItemArray[2].ToString();
                    this.TableList.Add(tableName);

                    string[] restrictionsColumns = new string[4];
                    restrictionsColumns[2] = tableName;
                    DataTable schemaColumns = connection.GetSchema("Columns", restrictionsColumns);

                    foreach (System.Data.DataRow rowColumn in schemaColumns.Rows)
                    {
                        string ColumnName = rowColumn[3].ToString();
                        this.ColumnList.Add(new Columns(){TableName= tableName, FieldName = ColumnName});
                    }

                    string[] restrictionsPrimaryKey = new string[4];
                    restrictionsPrimaryKey[2] = tableName;
                    DataTable schemaPrimaryKey = connection.GetSchema("IndexColumns", restrictionsColumns);


                    foreach (System.Data.DataRow rowPrimaryKey in schemaPrimaryKey.Rows)
                    {
                        string indexName = rowPrimaryKey[2].ToString();

                        if (indexName.IndexOf("PK_") != -1)
                        {
                            this.PrimaryKeyList.Add(new PrimaryKey()
                            {
                                TableName = tableName,
                                FieldName = rowPrimaryKey[6].ToString(),
                                PrimaryKeyName = indexName
                            });
                        }

                        if (indexName.IndexOf("UQ_") != -1)
                        {
                            this.UniqueKeyList.Add(new UniqueKey()
                            {
                                TableName = tableName,
                                FieldName = rowPrimaryKey[6].ToString(),
                                UniqueKeyName = indexName
                            });
                        }

                    }


                    string[] restrictionsForeignKeys = new string[4];
                    restrictionsForeignKeys[2] = tableName;
                    DataTable schemaForeignKeys = connection.GetSchema("ForeignKeys", restrictionsColumns);


                    foreach (System.Data.DataRow rowFK in schemaForeignKeys.Rows)
                    {

                        this.ForeignKeyList.Add(new ForeignKey()
                        {
                            ForeignName = rowFK[2].ToString(),
                            TableName = tableName,
                            // FieldName = rowFK[6].ToString() //There is no information
                        });                
                    }


                }


            }

        }

    }    

    public class Columns
    {
        public string TableName { get; set; }
        public string FieldName { get; set; }
    }

    public class PrimaryKey
    {
        public string TableName { get; set; }
        public string PrimaryKeyName { get; set; }
        public string FieldName { get; set; }
    }


    public class UniqueKey
    {
        public string TableName { get; set; }
        public string UniqueKeyName { get; set; }
        public string FieldName { get; set; }
    }

    public class ForeignKey
    {
        public string TableName { get; set; }
        public string ForeignName { get; set; }
       // public string FieldName { get; set; } //There is no information
    }

Как насчет вызова GetSchema () на вашем SqlConnection? Используя collectionName="IndexColumns" и список ограничений схемы вы можете запросить необходимую информацию с помощью GetSchema ().

посмотреть:

Как только я установил SqlConnection, используя имя базы данных, для меня сработало следующее:

var connectionString = 
    string.Format("Server=.\SQLEXPRESS;Database={0};Trusted_Connection=true", dbName);
using (var sqlConnection = new SqlConnection(connectionString))
{
    sqlConnection.Open();
    DataTable tables = sqlConnection.GetSchema("Tables");
    foreach (DataRow tablesRow in tables.Rows)
    {
        string tableName = tablesRow["table_name"].ToString();
        Console.WriteLine(tableName);
        var indexCols = sqlConnection.GetSchema("IndexColumns",
            new string[] {dbName, null, tableName, "PK_" + tableName, null});
        foreach (DataRow indexColsRow in indexCols.Rows)
            Console.WriteLine("  PK: {0}", indexColsRow["column_name"]);
    }
}