válida tipos tablas tabla restricciones relacionar referencial referencia para integridad hace externa datos codigo clave c# stored-procedures ado.net sql-server-2000 database-schema

c# - tipos - Cómo obtener columnas Restricciones de clave primaria usando SqlConnection.GetSchema()



la clave externa hace referencia a la tabla no válida (4)

No hay nada en la llamada a GetSchemaTable en SqlConnection que le permita resolver esto.

Podría parecer que puede IsKey , utilizando el valor de la columna IsKey , que debería ser verdadero para cualquier cosa que contribuya a identificar de manera única el registro en la tabla. Sin embargo, de la documentación para la columna IsKey (énfasis mío):

true: la columna es uno de un conjunto de columnas en el conjunto de filas que, en conjunto, identifica de manera única la fila. El conjunto de columnas con IsKey establecido en verdadero debe identificar de manera única una fila en el conjunto de filas. No hay ningún requisito de que este conjunto de columnas sea un conjunto mínimo de columnas. Este conjunto de columnas se puede generar a partir de una clave primaria de tabla base, una restricción única o un índice único .

Debido a esto, no puede garantizar que contribuya a una clave primaria per se.

Ahora, si todo lo que necesita es algo para identificar de manera única la fila, entonces IsKey está bien, ya que la clave principal no siempre es la forma de identificar de forma única una fila (por ejemplo, puede tener identificadores naturales con un índice único). Incluso si tiene una clave principal y un índice único con otras columnas, los valores en todas las columnas en combinación siempre serán únicos.

Sin embargo, si específicamente necesita mirar las columnas que componen la clave principal, entonces GetSchemaTable no le dará la información que necesita. En su lugar, puede hacer una llamada al procedimiento almacenado del sistema sp_pkeys para encontrar los nombres de las columnas que contribuyen a crear la clave principal.

Tengo un código de ADO.NET para detectar dinámicamente el esquema de la base de datos, lo que necesito es cómo obtener restricciones de columnas únicas y restricciones de clave primaria usando el método GetSchema en SqlConnection . Este es el código que tengo:

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();


En caso de que todavía alguien necesite una solución, he creado una función para esto, el comando Sql contiene la declaración en la que desea obtener la información del esquema.

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


¿Qué hay de llamar a GetSchema () en su SqlConnection? Usando collectionName="IndexColumns" y una lista de restricciones de esquema, puede solicitar la información que desee utilizando GetSchema ().

Ver:

Una vez que establecí SqlConnection usando el nombre de la base de datos, lo siguiente funcionó para mí:

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"]); } }


Puede obtener primaryKeys , UniqueKeys y ForeignKeys y cualquier otro esquema enumerado en la dataTable devuelta por este comando: "connection.GetSchema (" MetaDataCollections ")"

Debajo de un código que le devuelve las keysKeys y UniqueKeys (nombre de clave y nombre de columna).

Mira toda la documentación aquí

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 }