8

我有一些ADO.NET的代碼來動態檢測數據庫模式,我需要的是如何獲得唯一的列約束和主鍵約束使用GetSchema方法SqlConnection。這是我的代碼:如何獲得列主鍵約束使用SqlConnection.GetSchema()

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爲任何有助於唯一標識表中的記錄。然而,對於IsKey列(重點煤礦)的文檔:

真:列是在,採取 一起行集一組 列的一個,唯一地標識該行。 將IsKey設置爲 true的列的集合必須唯一標識行集合中的行 。沒有要求 這組列是最小的 組的列。可以從基表 主鍵,唯一約束或 唯一索引生成這組列 可能

因此,您不能保證它對主鍵的貢獻。因爲主鍵並不總是唯一標識一行的方式(例如,您可以擁有唯一索引的自然標識符)。所以,如果您只需要唯一標識該行,那麼IsKey就可以了。即使您有其他列的主鍵和唯一索引,跨所有這些列的值也將始終是唯一的。

但是,如果您特別需要查看組成主鍵的列,那麼GetSchemaTable將不會爲您提供所需的信息。相反,您可以撥打sp_pkeys系統存儲過程來查找有助於創建主鍵的列的名稱。

+0

感謝reply.from你的解釋我不明白,我需要改變我的上面C#你syntax.Will PLZ說什麼我需要改變我的代碼。謝謝 – shamim 2011-05-02 04:20:30

+0

@shamim:請參閱'sp_keys'存儲過程的鏈接,您將不得不調用此存儲過程來獲取組成表的主鍵的列。 – casperOne 2011-05-02 04:48:41

+0

在我上面的語法我使用sp_keys過程那裏我傳遞表名,在我的數據表中,我得到架構,但從架構我無法檢測主鍵。所以我尋求你的建議和help.Thanks – shamim 2011-05-02 05:02:43

2

如果仍然有人需要解決方案,我爲此創建了一個函數,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 
0

怎麼樣在你的SqlConnection上調用GetSchema()?使用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"]); 
    } 
} 
2

你可以得到primaryKeysUniqueKeysForeignKeys以及此命令返回的dataTable中列出的任何其他架構:"connection.GetSchema (" MetaDataCollections ")"

在返回您primaryKeys和UniqueKeys(鍵名稱和列名稱)的代碼下面。

看所有文件Here

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 
    }