现在的位置: 首页 > 综合 > 正文

Working with ADO.NET Schema APIs 使用ADO.NET 模式API

2013年09月10日 ⁄ 综合 ⁄ 共 6425字 ⁄ 字号 评论关闭

虽说翻译信,达,雅
本人不是翻译家,请多多指教
另外我已经修改文章中的错误词语(注意,技术内容有误的请前往原文站点)

原文 http://www.dotnetbips.com/articles/bcd9065e-94af-4063-8360-f916571f9872.aspx
导言
在大多数数据驱动的应用程序开发者处理SQL查询表示,选择,插入,更新或删除数据,从数据库中。然

而,有时你需要找回Schema

的信息从数据库中。假设你正在开发的应用程序进行数据输入和输出之间的两个或两个以上的数据库。

在应用程序运行时,一个好

的解决办法,你想检索表模式,而不是硬编码。幸运的是, ado.net提供了一整套的类库,让您可查询的

数据库模式。在这篇文章

中我将说明如何使用这些类库。
可行的办法
当你想检索数据库模式,你可以用几个技巧:
存储数据库模式信息到一些XML文件,然后在你的应用程序中读取这个XML文件。
使用系统存储过程的基础数据库(underlying database),以取回Schema的信息。
正如你可能已经猜到,第一个技术是不是那么好,因为生成的XML文件是一个手动操作。甚至第二种方

法有其自身的缺陷。所有数据

库都不可能用相同的存储过程来检索数据库模式。此外,它不保证这些存储过程返回的信息一致的方式

(manner)。考虑到这方面

的不足,这是值得探讨ado.net 模式的应用程序接口(API)模型。
GetSchema() 方法,无任何参数返回你所需要的元数据集合 。元数据的集合是一个集合来提供特定类型

的项(表,视图,存储过程

等) 元数据信息
GetSchema() 方法调用通过一个元数据集合名(a metadata collection name),返回在特殊集合中的

项。例如,如果你指定表元

数据集合,然后GetSchema() 方法将返回在数据库中所有表的信息。返回作为一个DataTable。
GetSchema() 方法调用通过一个元数据集合名(a metadata collection name)和限制(filter )条件

返回应用限制(filter )

条件的项。
元数据集合
元数据集合是一个包括有关项信息,其模式可予以检索。共同的元数据集合是:
表:数据库表的信息
视图:数据库视图的信息
列:表中列的信息
视图列(ViewColumns): 视图的列信息
存储过程:存储过程的信息
过程变量(参数):过程变量(参数)的信息
索引:索引的信息
索引列(IndexColumns ):索引列的信息
数据类型:数据类型的信息
用户:数据库用户信息
限制
元数据集合默认返回一个包含整个信息的项。举例来说,过程变量(参数)收集返回信息,系统中所有

存储过程的所有参数。在大

多数情况下,这不是你想要的。你想要一个具体存储过程的参数。这类有限制的条件(filtering )元数据

集合能够实现约束。一

个约束是一个字符串数组并且指明约束条件。不是所有的元数据集合共用同一个约束条件。特定的元数

据集合,有固定的限制条件

(表达式),它是可以确定的。举例来说,表的元数据集合,可以由表的目录名称,所有者名称和表名

称确定。其他元数据集合可

能会有其他的(或更少)的限制标准。

创建一个简单的数据库浏览器
为了说明我们讨论内容,让创建一个简单的数据库浏览器,如下图所示:
(见原文)
数据库浏览器简单地让你展示数据库,表,意见和存储程序在树。

首先,创建一个新的 Windows Forms application,在Visual Studio和拖放一TreeView。你需要一

个helper 方法,您可以从多个

地方以快速添加一个节点到TreeView。这个helper 方法如下所示:

private TreeNode AddNode(TreeNode parent,
string text,string tag,int imgIndex)
{
TreeNode child = new TreeNode(text);
child.ImageIndex = imgIndex;
child.SelectedImageIndex = imgIndex;
child.Tag = tag;
if (parent != null)
{
parent.Nodes.Add(child);
}
else
{
treeView1.Nodes.Add(child);
}
return child;
}该AddNode() helper 方法接受父节点,文本显示为新增节点,一个特殊的标签,为新的节点,节点显

示图标,使您稍后可以确认这节点。里面创建了一个新treenode和设置各种属性。若父节点对节点

是null的新节点是直接加入到该tree view,否则它得到附在一个孩子节点的父节点。 你需要更多helper

方法,命名为GetSchemaInfo()返回模式的信息,一个具体项。该GetSchemaInfo()方法,如下所

示:private DataTable GetSchemaInfo
(SchemaCollection collection,string entity)
{
DataTable dt = null;
string collectionname = "";
string[] restrictions = null;

switch (collection)
{
case SchemaCollection.Databases:
collectionname = "Databases";
if (entity != "")
{
restrictions = new string[1];
restrictions[0] = entity;
}
break;
case SchemaCollection.Tables:
collectionname = "Tables";
if (entity != "")
{
restrictions = new string[4];
restrictions[0] = entity;
}
break;
case SchemaCollection.Views:
collectionname = "Views";
if (entity != "")
{
restrictions = new string[3];
restrictions[0] = entity;
}
break;
case SchemaCollection.Columns:
collectionname = "Columns";
if (entity != "")
{
restrictions = new string[4];
restrictions[2] = entity;
}
break;
case SchemaCollection.ViewColumns:
collectionname = "ViewColumns";
if (entity != "")
{
restrictions = new string[4];
restrictions[2] = entity;
}
break;
case SchemaCollection.StoredProcedures:
collectionname = "Procedures";
if (entity != "")
{
restrictions = new string[4];
restrictions[0] = entity;
}
break;
case SchemaCollection.Parameters:
collectionname = "ProcedureParameters";
if (entity != "")
{
restrictions = new string[4];
restrictions[2] = entity;
}
break;
}
string strConn = ConfigurationManager.
ConnectionStrings["connstr"].ConnectionString;
SqlConnection cnn = new SqlConnection(strConn);
cnn.Open();
dt = cnn.GetSchema(collectionname,restrictions);
cnn.Close();
return dt;
}该getschemainfo ( )方法接受两个参数,参数从schemacollection枚举和名称的收

集。该schemacollection枚举是用户自定义枚举,如下所示:public enum SchemaCollection
{
Databases,
Tables,
Views,
StoredProcedures,
Columns,
ViewColumns,
Parameters
}

该schemacollection枚举简单说明了元数据集合,以用于检索模式的信息。

根据集合的名称可适用限制有所不同。例如,如果你使用的数据库集合,然后限制数组(restrictions

array )应包含仅有一个内容元素,显示要查询的数据库名称。在另一方面,如果你使用的表集合,然后

限制数组包含四个要素指定目录名称,所有者名称,表名称和表型。这同样适用于视图,列 , 视图

列viewcolumns ,存储过程和存储过程参数集合。那么代码检索数据库连接字符串来自应用程序的配置

文件。一个实例sqlconnection对象,创建并打开(open)。该getschema ( )方法传递通过集合名字

和限制数组,在连接被调用。该数据表,从而获得返回给调用者。

由于形式载荷你需要翻查资料的所有数据库,并显示数据库的名称在树的看法。这样做是form 的LOAD

事件的形式如下所示:
private void Form2_Load(object sender,
EventArgs e)
{
TreeNode root= treeView1.Nodes.Add("All Databases");
DataTable db = GetSchemaInfo
(SchemaCollection.Databases, "");
foreach (DataRow row in db.Rows)
{
AddNode(root, row["DATABASE_NAME"].ToString(),
"Database",0);
}
}
在这里,代码增加了一个根结与文本"所有数据库(All Databases)" 。然后调用getschemainfo ( )

方法,指明我们想检索的资料数据库资料。返回的数据表载列依赖于数据库。每一行都包含许多列。我

们使用database_name列显示的数据库名称。注意,加入加入标签节点的节点设置为"数据库" 。这样,

我们就能辨别标签节点代表了数据库或任何其他类型的项。
当用户选择某一节点,我们需要来移动其孩子节点。例如,如果一个节点代表了一个数据库,点击它应

该移动表,视图和存储过程。如果一个节点是一个表,点击它应移动其列资料等等。这个任务完成了

在nodemouseclick事件处理的TreeView控件。
private void treeView1_NodeMouseClick
(object sender, TreeNodeMouseClickEventArgs e)
{
DataTable dt = null;
if (e.Node.Tag != null)
{
e.Node.Nodes.Clear();
switch (e.Node.Tag.ToString())
{
case "Database":
TreeNode tblfolder=AddNode(e.Node,
 "Tables", null, 5);
tblfolder.SelectedImageIndex = 6;
TreeNode viewfolder = AddNode(e.Node,
 "Views", null, 5);
viewfolder.SelectedImageIndex = 6;
TreeNode procfolder = AddNode(e.Node,
 "Procedures", null, 5);
procfolder.SelectedImageIndex = 6;
dt = GetSchemaInfo(SchemaCollection.Tables,
e.Node.Text);
foreach (DataRow row in dt.Rows)
{
AddNode(tblfolder, row["TABLE_NAME"].ToString(),
"Table",1);
}
dt = GetSchemaInfo(SchemaCollection.StoredProcedures,
e.Node.Text);
foreach (DataRow row in dt.Rows)
{
AddNode(procfolder, row["SPECIFIC_NAME"].ToString(),
"Procedure",2);
}
dt = GetSchemaInfo(SchemaCollection.Views, e.Node.Text);
foreach (DataRow row in dt.Rows)
{
AddNode(viewfolder, row["TABLE_NAME"].ToString(),
 "View", 1);
}
break;
case "Table":
dt = GetSchemaInfo(SchemaCollection.Columns,
e.Node.Text);
foreach (DataRow row in dt.Rows)
{
AddNode(e.Node, row["COLUMN_NAME"].ToString() +
" (" + row["DATA_TYPE"].ToString() + "," +
(row["IS_NULLABLE"].ToString() == "YES" ? "NULL" :
"NOT NULL") + ")", "Column", 3);
}
break;
case "View":
dt = GetSchemaInfo(SchemaCollection.ViewColumns,
e.Node.Text);
foreach (DataRow row in dt.Rows)
{
AddNode(e.Node, row["COLUMN_NAME"].ToString(),
"ViewColumn", 3);
}
break;
case "Procedure":
dt = GetSchemaInfo(SchemaCollection.Parameters,
e.Node.Text);
foreach (DataRow row in dt.Rows)
{
AddNode(e.Node, row["PARAMETER_NAME"].ToString() +
" (" + row["DATA_TYPE"].ToString() + ")",
"Parameter", 4);
}
break;
}
}
}
以上代码调用同一getschemainfo ( )helper 方法取决于标签属性的树节点被点击了。如果标签是"数

据库" ,那么,表,视图和存储过程也要读取和移动。注意,数据表列名称用在for循环。表名,存储过

程的名称和视图名字取自table_name , specific_name和table_name列。

在其他情况下从事类似工作的标签值"表","视图"和"存储过程" 。列名称,数据类型和NULL的状态是来

自column_name , data_type和is_nullable栏目。同样,参数的名称和其数据类型是分别来

自parameter_name和data_type列。

然后再运行应用程序不要忘记添加数据库连接字符串在应用配置文件中,如下所示:

<connectionStrings>
<add
name="connstr"
connectionString="data source=./sqlexpress;
initial catalog=northwind;
integrated security=true"
providerName="System.Data.SqlClient"/>
</connectionStrings>
</configuration>

就是这么简单!现在你可以运行该应用程序,并尝试不同的导航的数据库对象。

 代码下载见原文站点

【上篇】
【下篇】

抱歉!评论已关闭.