![](/img/trans.png)
[英]How do I get a a Model I made from the ADO.net entity model designed to only return data dependent on a foreign key
[英]How do I get the primary key columns in ADO.NET?
我有一张桌子:
CREATE TABLE [dbo].[DeliveryData](
[DeliveryId] [int] IDENTITY(1,1) NOT NULL,
...
CONSTRAINT [PK_DeliveryData] PRIMARY KEY CLUSTERED
(
[DeliveryId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
和代码:
public void GetPrimaryKeyColumns(SqlConnection conn) {
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "select * from [dbo].[DeliveryData]";
SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SchemaOnly);
DataTable schema = reader.GetSchemaTable();
DataColumn[] columns = schema.PrimaryKey;
...
}
cmd,阅读器和架构都看起来不错,但是列的长度为零。 它不应该包含“ DeliveryId”吗? 如何获得主列“ DeliveryId”?
谢谢您的帮助!
布莱克
模式表不是DeliveryData
表。 您必须检查IsKey
true的架构表,然后获取ColumnName
字段。 然后,您可以使用它在常规数据表上找到真实列。
更新
GetSchemaTable()
返回元数据信息的数据表,您可以在文档中查看: https : //msdn.microsoft.com/zh-cn/library/system.data.sqlclient.sqldatareader.getschematable(v=vs.110) .aspx
如果要运行查询,返回的数据表中的行最终将与查询中的列数一样多。 这是我从数据库中的测试表获得的模式表的部分屏幕截图。 注意,每一列现在都是一行,IsKey字段会告诉您该列是否为键列:
如果要在DataTable上使用PrimaryKey
属性,请不要使用GetSchemaTable()
,只需使用SqlDataAdapter
填充常规DataTable。
更新2
使用CommandBehavior.KeyInfo
代替CommandBehavior.SchemaOnly
使用SMO
using Microsoft.SqlServer.Management.Smo;
....
Server svr = new Server("Your Server Name");
Database db = svr.Databases["Your Database Name"];
Table tbl = db.Tables["DeliveryData"];
foreach (Column c in tbl.Columns)
{
bool isAKeyColumn = c.InPrimaryKey
}
在所有情况下,使用GetSchemaTable,MSSQL都不会返回正确的主键信息。 (不足为奇。例如,几乎所有数据库供应商都比MS更好地支持ODBC。)但是,以下查询确实起作用:
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS as tc
LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE as kcu
ON kcu.CONSTRAINT_CATALOG = tc.CONSTRAINT_CATALOG
AND kcu.CONSTRAINT_SCHEMA = tc.CONSTRAINT_SCHEMA
AND kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
AND kcu.TABLE_CATALOG = tc.TABLE_CATALOG
AND kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA
AND kcu.TABLE_NAME = tc.TABLE_NAME
WHERE tc.CONSTRAINT_TYPE ='PRIMARY KEY'
AND tc.TABLE_SCHEMA = 'dbo'
AND tc.TABLE_NAME = 'DeliveryData'
ORDER BY ORDINAL_POSITION;
这是一个完整的解决方案:
public List<string> GetPrimaryKeyColumns(DbConnection conn, string schema, string table) {
DbCommand cmd = conn.CreateCommand();
DbParameter p = cmd.CreateParameter();
p.ParameterName = "@schema";
p.Value = schema;
p.DbType = DbType.String;
p.Direction = ParameterDirection.Input;
cmd.Parameters.Add(p);
p = cmd.CreateParameter();
p.ParameterName = "@table";
p.Value = table;
p.DbType = DbType.String;
p.Direction = ParameterDirection.Input;
cmd.Parameters.Add(p);
cmd.CommandText = @"SELECT kcu.COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS as tc
LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE as kcu
ON kcu.CONSTRAINT_CATALOG = tc.CONSTRAINT_CATALOG
AND kcu.CONSTRAINT_SCHEMA = tc.CONSTRAINT_SCHEMA
AND kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
-- AND kcu.TABLE_CATALOG = tc.TABLE_CATALOG doesn't work on MySQL
AND kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA
AND kcu.TABLE_NAME = tc.TABLE_NAME
WHERE tc.CONSTRAINT_TYPE ='PRIMARY KEY'
AND tc.TABLE_SCHEMA = @schema
AND tc.TABLE_NAME = @table
ORDER BY ORDINAL_POSITION";
DbDataReader reader = cmd.ExecuteReader(CommandBehavior.KeyInfo);
List<string> res = new List<string>();
while (reader.Read()) {
var str = reader[0];
if (str != System.DBNull.Value)
res.Add((string) str);
}
reader.Dispose();
cmd.Dispose();
return res;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.