深入了解新的公共元數據 在我的前一篇文章
我指出 Visual Studio
服務器資源管理器現在使用一個包含了
NET 數據提供程序(而不是 OLE DB 提供程序)列表的對話框來提示連接信息
當您確定一個連接字符串並添加數據連接時
每個數據連接也顯示一個關於通過連接直接可見的數據庫對象(如表
視圖和存儲過程)的信息的樹形結構
但這些信息來自哪裡呢?難道是 Visual Studio 僅為某些數據提供程序硬編碼來生成這個信息
而假如我編寫我自己的數據提供程序或者從第三方購買一個的時候
就留給我一個空節點?不
在 Visual Studio
中並不是這樣
由於 ADO
NET
中的新架構 API
所有這些有用的信息都將提供給您
我不知道這是否是 Visual Studio 做到它的方法
但是這裡就是使用新的 API 來獲得一個數據庫中的表的列表的代碼
// uses a ADO
NET
named connection string in config file
// uses ADO
NET
ProviderFactory and base classes
// see previous article
public static void GetListOfTables(string connectstring_name)
{
ConnectionStringSettings s =
ConfigurationSettings
ConnectionStrings[connectstring_name];
DbProviderFactory f = DbProviderFactories
GetFactory(s
ProviderName);
using (DbConnection conn = f
CreateConnection())
{
conn
ConnectionString = s
ConnectionString;
conn
Open();
DataTable t = conn
GetSchema(
Tables
);
t
WriteXml(
tables
xml
);
}
}
究竟誰需要元數據? 元數據是每個數據訪問 API 的一部分
盡管元數據的主要使用者是像 Visual Studio 這樣的工具或者像 DeKlarit 這樣的代碼生成器
但是它們並不是惟一的使用者
應用程序包設計師可能允許最終用戶通過向現有的表添加新表或新列來自定義一個應用程序
當最終用戶如此改變了數據庫架構時
一個通用查詢和修改工具可以在維護
備份和其他應用程序函數中使用元數據來包含用戶的新表
就像它們是應用程序附帶的內置表一樣
程序員可以使用元數據來編寫他們自己的派生自 System
Data
Common
DbCommandBuilder的自定義類
並為使用 DataSet 創建插入
更新和刪除命令
多數據庫應用程序(即設計為在用戶選擇的數據庫上運行的應用程序)的構建者可以盡可能多地使用元數據來維護公共代碼庫
在需要時優化數據訪問代碼
通過一般元數據 API 來公開元數據要比讓每個使用者使用特定於數據庫的 API 要好
這樣
工具編寫人員可以維護一個可管理性更好的代碼庫
這樣的 API 還必須是非常靈活的
因為在編寫一般 API 來公開元數據時有四個障礙需要考慮
元數據集合和信息在數據庫間是有差別的
例如
SQL Server 用戶可能想要公開一個鏈接服務器的集合
但是 Oracle 用戶可能對關於 Oracle 序列的信息感興趣
不僅在不同的數據庫產品中
而且即使在相同數據庫的不同版本中
存儲公共數據庫元數據的基礎系統表都是不同的
例如
SQL Server
使用在一個
sys
架構下的新表(例如
sys
tables)公開它的元數據
而 SQL Server 以前的版本使用元數據表(如 sysobjects£©來存儲相同的數據
不同的程序可能有不同的元數據視圖
以一個例子來說
許多程序員抱怨 Oracle 數據庫中表的列表太長
因為大多數元數據 API 將
system
表與用戶表混在一起
他們想要一個僅由他們定義的表組成的短列表
是否根本不支持元數據
要提供多少元數據
應該完全取決於提供程序的編寫者
大部分數據庫 API 提供一個標准的元數據集
它是所有提供程序必須支持的
並且允許提供程序編寫者添加新的元數據表
這與使用 ANSI SQL 標准采用的方法是一致的
解決這一問題的標准的一部分是 Schema Schemata(INFORMATION_SCHEMA 和 DEFINITION_SCHEMA)的第
部分
ANSI SQL INFORMATION_SCHEMA 定義了由一個兼容的數據庫支持的標准的元數據視圖集
但即便是這個規范也需要有一個方法來解決上面這些問題
它聲明
實施者可以自由添加額外的表到 INFORMATION_SCHEMA 或添加額外的列到預定義的INFORMATION_SCHEMA 表
OLE DB 作為一個與 ANSI SQL 標准概念一致的數據訪問 API 示例
定義了一系列的名為
架構行集合
的元數據
它從一個大致遵循 INFORMATION_SCHEMA 的預定義集開始
並添加 OLE DB 特定的列到每個行中
ADO
NET
提供了一個甚至更強大更靈活的機制來公開元數據
我能得到什麼樣的元數據? ADO
NET
允許提供程序編寫者公開
種不同類型的元數據
這些主要的元數據 —
元數據集合
或
類別
— 在 System
Data
Common
DbMetaDataCollectionNames 類中被枚舉出來
; MetaDataCollections — 可用元數據集合的列表
; Restrictions — 對於每個元數據集合
存在一批可以用於限制被請求的架構信息范圍的限定符
; DataSourceInformation — 關於數據提供程序引用的數據庫實例的信息
; DataTypes — 一組關於數據庫支持的每個數據類型的信息
; ReservedWords — 適用於該種數據庫查詢語言的保留字
通常
查詢語言
等同於一種 SQL 的方言
MetaDataCollections 是 INFORMATION_SCHEMA 集合的名稱
如
表
列
或
主鍵
但是
如果使用 DbConnection
GetSchema
這些元數據類別也被認為是元數據
這意味著在代碼方面來說是這樣
這些集合可以像普通的元數據一樣被獲得
// gets information about database Views
Table t
= conn
GetSchema(
Views
);
// gets information about collections exposed by this provider
// this includes the five
meta
collections
described above
Table t
= conn
GetSchema(DbMetaDataCollectionNames
MetaDataCollections);
// gets information about the Restrictions meta
collection
Table t
= conn
GetSchema(DbMetaDataCollectionNames
Restrictions);
// No argument overload is same as asking for MetaDataCollections
Table t
= conn
GetSchema();
個元數據集合中的
個值得進一步解釋
Restrictions
Restrictions 可以用來限制返回元數據的數量
如果您熟悉 OLE DB 或 ADO
那麼術語
restriction
意味著在那些 API 中同樣的內容
作為示例
讓我們使用 MetaDataCollection
列
它是表中的列名稱的集合
這個集合可以用於獲取所有表中的所有列
但是
此被請求的列集合會被數據庫名稱
所有者/架構或者表限制
每個元數據集合可以有不同數量的可能限制
並且每個限制會有一個默認值
在我們下面的示例中
這裡是一個對列元數據的限制的 XML 表示
清單
列集合上的 Restrictions(XML 格式)
<Restrictions>
<CollectionName>Columns</CollectionName>
<RestrictionName>Catalog</RestrictionName>
<RestrictionDefault>table_catalog</RestrictionDefault>
<RestrictionNumber>
</RestrictionNumber>
</Restrictions> <Restrictions>
<CollectionName>Columns</CollectionName>
<RestrictionName>Owner</RestrictionName>
<RestrictionDefault>table_schema</RestrictionDefault>
<RestrictionNumber>
</RestrictionNumber>
</Restrictions> <Restrictions>
<CollectionName>Columns</CollectionName>
<RestrictionName>Table</RestrictionName>
<RestrictionDefault>table_name</RestrictionDefault>
<RestrictionNumber>
</RestrictionNumber>
</Restrictions> <Restrictions>
<CollectionName>Columns</CollectionName>
<RestrictionName>Column</RestrictionName>
<RestrictionDefault>column_name</RestrictionDefault>
<RestrictionNumber>
</RestrictionNumber>
</Restrictions>
Restrictions 是使用一個重載的 DbConnection
GetSchema 指定的
這些限制被指定為一個數組
您可以將一個數組指定為和整個限制集合或者一個子集數組一樣大
因為
RestrictionNumbers
通常從最少限制向最多限制發展
對您想要省略的限制值使用空值(不是數據庫 NULL
而是
NET NULL
或者在 Visual Basic
NET 中的 Nothing)
例如
// restriction string array
string[] res = new string[
];
// all columns
all tables owned by dbo
res[
] =
dbo
;
DataTable t
= conn
GetSchema(
Columns
res);
// clear collection
for (int i =
; i <
; i++) res[i] = null;
// all columns
all tables named
authors
any owner/schema
res[
] =
authors
;
DataTable t
= conn
GetSchema(
Columns
res);
// clear collection
for (int i =
; i <
; i++) res[i] = null;
// columns named au_lname
// all tables named
authors
any owner/schema
res[
] =
authors
;
From:http://tw.wingwit.com/Article/program/net/201311/11456.html