![](/img/trans.png)
[英]How can I use SqlConnection.GetSchema to get synonym information?
[英]How to get columns Primary key constraints using SqlConnection.GetSchema()
我有一些 ADO.NET 代码来动态检测数据库模式,我需要的是如何使用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();
在SqlConnection
上对GetSchemaTable
的调用中没有任何内容可以让您弄清楚这一点。
您似乎可以使用IsKey
列值,对于有助于唯一标识表中记录的任何内容,它都应该返回 true。 但是,从IsKey
列的文档(强调我的):
true:该列是行集中的一组列之一,它们一起唯一标识该行。 IsKey 设置为 true 的列集必须唯一标识行集中的行。 不要求此列集是最小列集。 这组列可以从基表主键、唯一约束或唯一索引生成。
因此,您不能保证它对主键本身有贡献。
现在,如果您只需要唯一标识行的东西,那么IsKey
就可以了,因为主键并不总是唯一标识行的方法(例如,您可以使用具有唯一索引的自然标识符)。 即使您有一个主键和一个包含其他列的唯一索引,所有这些列组合中的值也将始终是唯一的。
但是,如果您特别需要查看构成主键的列,则GetSchemaTable
不会为您提供所需的信息。 相反,您可以调用sp_pkeys
系统存储过程来查找有助于生成主键的列的名称。
如果仍然有人需要解决方案,我为此创建了 function,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
您可以获取此命令返回的 dataTable 中列出的primaryKeys
、 UniqueKeys
和ForeignKeys
以及任何其他架构: "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
}
在 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"]);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.