Как получить ограничения первичного ключа столбцов с помощью 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"]);
}
}