日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

ADO.NET 2.0 中的架构

發(fā)布時(shí)間:2023/11/27 生活经验 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ADO.NET 2.0 中的架构 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Bob Beauchemin
DevelopMentor

適用于:
Microsoft ADO.NET 2.0
Microsoft Visual Studio 2005
C# 編程語言

摘要:了解在 ADO.NET 中對(duì)于從您的數(shù)據(jù)源訪問元數(shù)據(jù)的增強(qiáng)支持。

下載相關(guān)的 SchemasSample.exe 示例代碼。

本頁內(nèi)容
深入了解新的公共元數(shù)據(jù) API
究竟誰需要元數(shù)據(jù)?
我能得到什么樣的元數(shù)據(jù)?
Restrictions
DataSourceInformation
自定義并擴(kuò)展元數(shù)據(jù)
用戶自定義
小結(jié):元數(shù)據(jù)支持的最終部分

深入了解新的公共元數(shù)據(jù) API

在我的前一篇文章,我指出 Visual Studio 2005 服務(wù)器資源管理器現(xiàn)在使用一個(gè)包含了 .NET 數(shù)據(jù)提供程序(而不是 OLE DB 提供程序)列表的對(duì)話框來提示連接信息。當(dāng)您確定一個(gè)連接字符串并添加數(shù)據(jù)連接時(shí),每個(gè)數(shù)據(jù)連接也顯示一個(gè)關(guān)于通過連接直接可見的數(shù)據(jù)庫對(duì)象(如表、視圖和存儲(chǔ)過程)的信息的樹形結(jié)構(gòu)。但這些信息來自哪里呢?難道是 Visual Studio 僅為某些數(shù)據(jù)提供程序硬編碼來生成這個(gè)信息,而假如我編寫我自己的數(shù)據(jù)提供程序或者從第三方購買一個(gè)的時(shí)候,就留給我一個(gè)空節(jié)點(diǎn)?不,在 Visual Studio 2005 中并不是這樣。由于 ADO.NET 2.0 中的新架構(gòu) API,所有這些有用的信息都將提供給您。我不知道這是否是 Visual Studio 做到它的方法,但是這里就是使用新的 API 來獲得一個(gè)數(shù)據(jù)庫中的表的列表的代碼。

// uses a ADO.NET 2.0 named connection string in config file
// uses ADO.NET 2.0 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");}
} 
返回頁首

究竟誰需要元數(shù)據(jù)?

元數(shù)據(jù)是每個(gè)數(shù)據(jù)訪問 API 的一部分。盡管元數(shù)據(jù)的主要使用者是像 Visual Studio 這樣的工具或者像 DeKlarit 這樣的代碼生成器,但是它們并不是惟一的使用者。應(yīng)用程序包設(shè)計(jì)師可能允許最終用戶通過向現(xiàn)有的表添加新表或新列來自定義一個(gè)應(yīng)用程序。當(dāng)最終用戶如此改變了數(shù)據(jù)庫架構(gòu)時(shí),一個(gè)通用查詢和修改工具可以在維護(hù)、備份和其他應(yīng)用程序函數(shù)中使用元數(shù)據(jù)來包含用戶的新表,就像它們是應(yīng)用程序附帶的內(nèi)置表一樣。程序員可以使用元數(shù)據(jù)來編寫他們自己的派生自 System.Data.Common.DbCommandBuilder的自定義類,并為使用 DataSet 創(chuàng)建插入、更新和刪除命令。多數(shù)據(jù)庫應(yīng)用程序(即設(shè)計(jì)為在用戶選擇的數(shù)據(jù)庫上運(yùn)行的應(yīng)用程序)的構(gòu)建者可以盡可能多地使用元數(shù)據(jù)來維護(hù)公共代碼庫,在需要時(shí)優(yōu)化數(shù)據(jù)訪問代碼。

通過一般元數(shù)據(jù) API 來公開元數(shù)據(jù)要比讓每個(gè)使用者使用特定于數(shù)據(jù)庫的 API 要好。這樣,工具編寫人員可以維護(hù)一個(gè)可管理性更好的代碼庫。這樣的 API 還必須是非常靈活的,因?yàn)樵诰帉懸话?API 來公開元數(shù)據(jù)時(shí)有四個(gè)障礙需要考慮。

1.

元數(shù)據(jù)集合和信息在數(shù)據(jù)庫間是有差別的。例如,SQL Server 用戶可能想要公開一個(gè)鏈接服務(wù)器的集合,但是 Oracle 用戶可能對(duì)關(guān)于 Oracle 序列的信息感興趣。

2.

不僅在不同的數(shù)據(jù)庫產(chǎn)品中,而且即使在相同數(shù)據(jù)庫的不同版本中,存儲(chǔ)公共數(shù)據(jù)庫元數(shù)據(jù)的基礎(chǔ)系統(tǒng)表都是不同的。例如,SQL Server 2005 使用在一個(gè)“sys”架構(gòu)下的新表(例如,sys.tables)公開它的元數(shù)據(jù),而 SQL Server 以前的版本使用元數(shù)據(jù)表(如 sysobjects£?來存儲(chǔ)相同的數(shù)據(jù)。

3.

不同的程序可能有不同的元數(shù)據(jù)視圖。以一個(gè)例子來說,許多程序員抱怨 Oracle 數(shù)據(jù)庫中表的列表太長,因?yàn)榇蠖鄶?shù)元數(shù)據(jù) API 將“system”表與用戶表混在一起。他們想要一個(gè)僅由他們定義的表組成的短列表。

4.

是否根本不支持元數(shù)據(jù),要提供多少元數(shù)據(jù),應(yīng)該完全取決于提供程序的編寫者。

大部分?jǐn)?shù)據(jù)庫 API 提供一個(gè)標(biāo)準(zhǔn)的元數(shù)據(jù)集,它是所有提供程序必須支持的,并且允許提供程序編寫者添加新的元數(shù)據(jù)表。這與使用 ANSI SQL 標(biāo)準(zhǔn)采用的方法是一致的。解決這一問題的標(biāo)準(zhǔn)的一部分是 Schema Schemata(INFORMATION_SCHEMA 和 DEFINITION_SCHEMA)的第 11 部分。ANSI SQL INFORMATION_SCHEMA 定義了由一個(gè)兼容的數(shù)據(jù)庫支持的標(biāo)準(zhǔn)的元數(shù)據(jù)視圖集。但即便是這個(gè)規(guī)范也需要有一個(gè)方法來解決上面這些問題。它聲明:

“實(shí)施者可以自由添加額外的表到 INFORMATION_SCHEMA 或添加額外的列到預(yù)定義的INFORMATION_SCHEMA 表。”

OLE DB 作為一個(gè)與 ANSI SQL 標(biāo)準(zhǔn)概念一致的數(shù)據(jù)訪問 API 示例,定義了一系列的名為“架構(gòu)行集合”的元數(shù)據(jù)。它從一個(gè)大致遵循 INFORMATION_SCHEMA 的預(yù)定義集開始,并添加 OLE DB 特定的列到每個(gè)行中。ADO.NET 2.0 提供了一個(gè)甚至更強(qiáng)大更靈活的機(jī)制來公開元數(shù)據(jù)。

返回頁首

我能得到什么樣的元數(shù)據(jù)?

ADO.NET 2.0 允許提供程序編寫者公開 5 種不同類型的元數(shù)據(jù)。這些主要的元數(shù)據(jù) — “元數(shù)據(jù)集合”或“類別” — 在 System.Data.Common.DbMetaDataCollectionNames 類中被枚舉出來。

?

MetaDataCollections — 可用元數(shù)據(jù)集合的列表。

?

Restrictions — 對(duì)于每個(gè)元數(shù)據(jù)集合,存在一批可以用于限制被請(qǐng)求的架構(gòu)信息范圍的限定符。

?

DataSourceInformation — 關(guān)于數(shù)據(jù)提供程序引用的數(shù)據(jù)庫實(shí)例的信息。

?

DataTypes — 一組關(guān)于數(shù)據(jù)庫支持的每個(gè)數(shù)據(jù)類型的信息。

?

ReservedWords — 適用于該種數(shù)據(jù)庫查詢語言的保留字。通常“查詢語言”等同于一種 SQL 的方言。

MetaDataCollections 是 INFORMATION_SCHEMA 集合的名稱,如“表”、“列”或“主鍵”。但是,如果使用 DbConnection.GetSchema,這些元數(shù)據(jù)類別也被認(rèn)為是元數(shù)據(jù)。這意味著在代碼方面來說是這樣,這些集合可以像普通的元數(shù)據(jù)一樣被獲得。

// gets information about database Views
Table t1 = conn.GetSchema("Views");
// gets information about collections exposed by this provider
// this includes the five "meta-collections" described above
Table t2 = conn.GetSchema(DbMetaDataCollectionNames.MetaDataCollections);
// gets information about the Restrictions meta-collection
Table t3 = conn.GetSchema(DbMetaDataCollectionNames.Restrictions);
// No argument overload is same as asking for MetaDataCollections
Table t4 = conn.GetSchema();

5 個(gè)元數(shù)據(jù)集合中的 2 個(gè)值得進(jìn)一步解釋。

返回頁首

Restrictions

Restrictions 可以用來限制返回元數(shù)據(jù)的數(shù)量。如果您熟悉 OLE DB 或 ADO,那么術(shù)語“restriction”意味著在那些 API 中同樣的內(nèi)容。作為示例,讓我們使用 MetaDataCollection“列”,它是表中的列名稱的集合。這個(gè)集合可以用于獲取所有表中的所有列。但是,此被請(qǐng)求的列集合會(huì)被數(shù)據(jù)庫名稱、所有者/架構(gòu)或者表限制。每個(gè)元數(shù)據(jù)集合可以有不同數(shù)量的可能限制,并且每個(gè)限制會(huì)有一個(gè)默認(rèn)值。在我們下面的示例中,這里是一個(gè)對(duì)列元數(shù)據(jù)的限制的 XML 表示:

清單 1. 列集合上的 Restrictions(XML 格式)

<Restrictions> <CollectionName>Columns</CollectionName> <RestrictionName>Catalog</RestrictionName> <RestrictionDefault>table_catalog</RestrictionDefault> <RestrictionNumber>1</RestrictionNumber> </Restrictions> <Restrictions> <CollectionName>Columns</CollectionName> <RestrictionName>Owner</RestrictionName> <RestrictionDefault>table_schema</RestrictionDefault> <RestrictionNumber>2</RestrictionNumber> </Restrictions> <Restrictions> <CollectionName>Columns</CollectionName> <RestrictionName>Table</RestrictionName> <RestrictionDefault>table_name</RestrictionDefault> <RestrictionNumber>3</RestrictionNumber> </Restrictions> <Restrictions> <CollectionName>Columns</CollectionName> <RestrictionName>Column</RestrictionName> <RestrictionDefault>column_name</RestrictionDefault> <RestrictionNumber>4</RestrictionNumber> 
</Restrictions> 

Restrictions 是使用一個(gè)重載的 DbConnection.GetSchema 指定的。這些限制被指定為一個(gè)數(shù)組。您可以將一個(gè)數(shù)組指定為和整個(gè)限制集合或者一個(gè)子集數(shù)組一樣大,因?yàn)椤癛estrictionNumbers”通常從最少限制向最多限制發(fā)展。對(duì)您想要省略的限制值使用空值(不是數(shù)據(jù)庫 NULL,而是 .NET NULL,或者在 Visual Basic .NET 中的 Nothing)。例如:

// restriction string array
string[] res = new string[4];// all columns, all tables owned by dbo
res[1] = "dbo";
DataTable t1 = conn.GetSchema("Columns", res);// clear collection
for (int i = 0; i < 4; i++) res[i] = null;
// all columns, all tables named "authors", any owner/schema
res[2] = "authors";
DataTable t2 = conn.GetSchema("Columns", res);// clear collection
for (int i = 0; i < 4; i++) res[i] = null;
// columns named au_lname 
// all tables named "authors", any owner/schema
res[2] = "authors";  res[3] = "au_lname";
DataTable t3 = conn.GetSchema("Columns", res);// clear collection
for (int i = 0; i < 4; i++) res[i] = null;
// columns named au_lname 
// any tables, any owner/schema
res[3] = "name";
DataTable t4 = conn.GetSchema("Columns", res);

您無需指定整個(gè)限制數(shù)組。在上面的情況中,這里您只想看到“dbo”擁有的表中的列,您可以指定一個(gè)只帶有兩個(gè)而不是全部四個(gè)成員的數(shù)組。也請(qǐng)注意,將一個(gè)空字符串指定為一個(gè)限制與指定一個(gè) null(在 Visual Basic .NET 中為 Nothing)值是不同的。您不必記住這些限制,您始終可以查詢它們,就像任何其他集合一樣。“Restrictions”集合本身不允許限制,但是因?yàn)樾畔⒈惶崛〉?DataTable 中,所以您可以使用一個(gè) DataView 來提供相似的功能,如下所示。

DataTable tv = conn.GetSchema(DbMetaDataCollectionNames.Restrictions);
DataView v = tv.DefaultView;
// show restrictions on the "Columns" collection, sorted by number
v.RowFilter = "CollectionName = 'Columns'";
v.Sort = "RestrictionNumber";
for (int i = 0; i < tv.Count; i++)Console.WriteLine("{0} (default){1}",tv.Rows[i]["RestrictionName"], tv.Rows[i]["RestrictionDefault"]);
返回頁首

DataSourceInformation

DataSourceInformation 集合為查詢生成器提供關(guān)于當(dāng)前數(shù)據(jù)庫(數(shù)據(jù)源)實(shí)例的信息。雖然這個(gè)集合可包含提供程序需要的任何內(nèi)容,但在 Microsoft 提供程序 (SqlClient、OracleClient、OleDb、Odbc) 中,這個(gè)集合包含相似的信息。這里是您默認(rèn)獲得的信息。

表 1. 在 Microsoft 提供程序中的 DataSourceInformation
格式/意義

CompositeIdentifierSeparatorPattern

多部分名稱的分隔符(如 pubs.dbo.authors 中的點(diǎn))

DataSourceProductName

數(shù)據(jù)庫名稱

DataSourceProductVersion

數(shù)據(jù)庫版本。請(qǐng)注意這是當(dāng)前通過 DbConnection 訪問的數(shù)據(jù)庫實(shí)例的版本。

DataSourceProductVersionNormalized

?

GroupByBehavior

枚舉,System.Data.Common.GroupByBehavior

IdentifierPattern

正則表達(dá)式字符串

IdentifierCase

枚舉,System.Data.Common.IdentifierCase

OrderByColumnsInSelect

布爾值,默認(rèn)情況下您應(yīng)該在一個(gè) SELECT 語句中 ORDER BY 這些列

ParameterMarkerFormat

說明參數(shù)標(biāo)記是否以一個(gè)特殊的字符開始(如 T-SQL 中的 @)

ParameterMarkerPattern

用于創(chuàng)建參數(shù)的正則表達(dá)式字符串

ParameterNameMaxLength

參數(shù)的最大長度

ParameterNamePattern

用于創(chuàng)建參數(shù)的正則表達(dá)式字符串

QuotedIdentifierPattern

用于引用標(biāo)識(shí)符的正則表達(dá)式字符串

QuotedIdentifierCase

枚舉,System.Data.Common.IdentifierCase

StatementSeparatorPattern

正則表達(dá)式字符串

StringLiteralPattern

正則表達(dá)式字符串

SupportedJoinOperators

枚舉,System.Data.Common.SupportedJoinOperators

對(duì)特定的數(shù)據(jù)庫方言來說有太多的信息來產(chǎn)生 SQL 了,您不這樣認(rèn)為么?還有一條信息我想要說一下,那就是提供程序是否在參數(shù)化查詢中使用命名參數(shù)或者位置參數(shù)。在我關(guān)于編寫?yīng)毩⒂谔峁┏绦虻拇a的上一篇文章中,我將命名和位置參數(shù)作為編寫參數(shù)化命令的兩種方法來討論。

返回頁首

自定義并擴(kuò)展元數(shù)據(jù)

既然我們已經(jīng)看到了提供的基礎(chǔ)元數(shù)據(jù)并且可以圍繞 DbConnection.GetSchema() 找到我們的方法,讓我們討論提供程序編寫者使用簡單的聲明性格式自定義元數(shù)據(jù)的方法,以及程序員如何能夠掛鉤到那種格式中。這個(gè)討論與文章開始的元數(shù)據(jù)復(fù)雜性相關(guān):如何提供獨(dú)立于數(shù)據(jù)庫版本的元數(shù)據(jù)以及如何處理不同使用者可能需要相同元數(shù)據(jù)的不同視圖的事實(shí)。

首先,讓我們指出元數(shù)據(jù)支持完全是可選的。提供程序不必支持 DbConnection.GetSchema,這種方法會(huì)引發(fā) NotSupportedException。此外,如果提供程序編寫者選擇支持 DbConnection.GetSchema,只有 MetaDataCollections 類別是必需的。提供程序可以選擇不提供任何或所有其他 4 個(gè)類別的信息。

其次,每個(gè)提供程序可以公開相同元數(shù)據(jù)集合的不同信息。例如,Tables 集合的結(jié)構(gòu)完全取決于提供程序編寫者。舉個(gè)例子,SqlClient 提供程序在 Tables 集合中公開了 4 個(gè)信息項(xiàng):table_catalog、table_schema、table_name 和 table_type。OracleClient 提供程序僅公開了 3 個(gè)信息項(xiàng)(OWNER、TABLE_NAME 和 TYPE),因?yàn)?Oracle 數(shù)據(jù)庫不包含多種目錄。對(duì)每個(gè)提供程序來說限制和限制項(xiàng)的數(shù)量可以是不同的。再次以表的情況為例,SqlClient 提供程序支持 4 個(gè)限制,而 OracleClient 提供程序只支持 2 個(gè)。限制也不必按照任何指定的順序發(fā)生。所以與在 OLE DB 和 ODBC API 中不同,這里沒有委托管理的元數(shù)據(jù)結(jié)構(gòu)、大量元數(shù)據(jù)或者元數(shù)據(jù)順序。提供程序可以自由公開任何相關(guān)的元數(shù)據(jù)。但是,如果一個(gè)特定的應(yīng)用程序(如 Visual Studio)要求在一個(gè)應(yīng)用程序里使用的所有 .NET 數(shù)據(jù)提供程序中元數(shù)據(jù)是一致的,它也能夠通過覆蓋提供程序的標(biāo)準(zhǔn)行為來獲得這個(gè)行為。我們將在后面的用戶自定義小節(jié)進(jìn)一步討論這個(gè)問題。

提供程序編寫者可以將元數(shù)據(jù)邏輯直接硬編碼到他們的提供程序中,每個(gè)提供程序編寫者為了獲得相似的元數(shù)據(jù)可以使用不同的內(nèi)部算法。例如,在實(shí)現(xiàn) OLE DB 的 ISchemaRowset 方法時(shí),這就是過去完成它的方法。但是,在 ADO.NET 2.0 中,在 System.Data.ProviderBase 命名空間中有一些基類是提供程序編寫者可用的。4 個(gè)可用的 Microsoft 提供程序使用這些基類,因此它們都以相似的方法實(shí)現(xiàn)架構(gòu)。我將用這個(gè)實(shí)現(xiàn)進(jìn)行講解,希望大多數(shù)編寫提供程序的程序員喜歡 DataDirect 技術(shù),而其他提供程序編寫者也使用它。

公開元數(shù)據(jù)的基類是 DbMetaDataFactory。實(shí)現(xiàn)它的一個(gè)子類的提供程序使用一個(gè) XML 文件來定義其元數(shù)據(jù)提取行為。這些文件是在 System.Data.dll 和 System.Data.OracleClient.dll 中嵌入的資源,您可以通過從命令行運(yùn)行 ILDASM.exe 來查看原始的 XML 文件。

>ildasm.exe System.Data.dll /out:dummy.il

查看從 ILDASM 生成的 XML 資源文件,如同剝開了洋蔥的另一層。這個(gè)文件枚舉了被支持的集合以及包含在每個(gè)元數(shù)據(jù)集合(通過架構(gòu))中的信息,并且看起來是使用 DataSet.WriteXml(XmlWriteMode.WriteSchema) 重載的 DataSet.WriteXml 方法的輸出。最有趣的部分是在除了 DataSourceInformation 和 MetaDataCollections 元素中的 PopulationMechanism/PopulationString 子元素以外的所有元數(shù)據(jù)集合中的 MinimumVersion/MaximumVersion 元素。

使用 MinimumVersion/MaximumVersion 允許提供程序編寫者指定對(duì)于不同版本的數(shù)據(jù)庫要執(zhí)行哪些元數(shù)據(jù)查詢。通過使用單個(gè) MetaDataCollection 的多個(gè)元素,您可以使 GetSchema 對(duì)不同版本的數(shù)據(jù)庫表現(xiàn)不同。舉一個(gè)明顯的例子,您可以使用與以前版本的 SQL Server 不同的 SQL Server 2005 各版本。這里是一個(gè)使用來自 SQL Server 元數(shù)據(jù)資源 (System.Data.SqlClient.SqlMetaData) 的 MinimumVersion 的例子:

清單 2. 數(shù)據(jù)類型集合中的數(shù)據(jù)類型 XML 的元數(shù)據(jù)項(xiàng)

<DataTypes> <TypeName>xml</TypeName> <ProviderDbType>25</ProviderDbType> <ColumnSize>2147483647</ColumnSize><DataType>System.String</DataType> <IsAutoIncrementable>false</IsAutoIncrementable><IsCaseSensitive>false</IsCaseSensitive> <IsFixedLength>false</IsFixedLength> <IsFixedPrecisionScale>false</IsFixedPrecisionScale> <IsLong>true</IsLong> <IsNullable>true</IsNullable> <IsSearchable>true</IsSearchable> <IsSearchableWithLike>false</IsSearchableWithLike> <MinimumVersion>09.00.000.0</MinimumVersion> <IsLiteralSupported>false</IsLiteralSupported> 
</DataTypes> 

這定義了關(guān)于 SQL Server 數(shù)據(jù)類型 XML 的信息。MinimumVersion 指示出,這個(gè)數(shù)據(jù)類型只在使用 SQL Server 2005 時(shí)可用。如果您要求 SqlConnection.GetSchema 提供數(shù)據(jù)庫支持的數(shù)據(jù)類型列表,只有 SQL Server 2005 的各版本數(shù)據(jù)庫(SQL Server 2005 是版本 9,當(dāng)前的beta 2 版是 09.00.852.2)會(huì)報(bào)告它們支持 XML 數(shù)據(jù)類型。

對(duì)于通常被 INFORMATION_SCHEMA(如表、視圖或存儲(chǔ)過程)公開的集合,PopulationMechanism 和 PopulationString 是工作開始的地方。在這個(gè)實(shí)現(xiàn)中使用了三個(gè) PopulationMechanisms:DataTableSQLCommandPrepareCollection。DataTable 用于填充元數(shù)據(jù)集合。使用 DataTable 意味著用于填充集合的信息是在 XML 資源文件本身當(dāng)中。在每種情況下,PopulationString 是當(dāng) XML 資源文件加載到一個(gè) .NET DataSet 時(shí),生成的 DataTable 的名稱。SQLCommand 意味著提供程序?qū)⑹褂靡粋€(gè) DbCommand 實(shí)例來發(fā)出對(duì)數(shù)據(jù)庫的命令。如果您查看由 SQLCommand 產(chǎn)生的集合的一個(gè) PopulationString:

清單 3. SQL Server 中的數(shù)據(jù)庫(目錄)項(xiàng) — MetaDataCollection

<MetaDataCollections> <CollectionName>Databases</CollectionName> <NumberOfRestrictions>1</NumberOfRestrictions> <NumberOfIdentifierParts>1</NumberOfIdentifierParts> <PopulationMechanism>SQLCommand</PopulationMechanism> <PopulationString>select name as database_name, dbid, crdate as create_date from master..sysdatabases where name = {0}</PopulationString> 
</MetaDataCollections> 

當(dāng)限制在 DbConnection.GetSchema 中使用時(shí),很容易就能夠推斷出字符串替換將被應(yīng)用到“基查詢”中。如果沒有限制被指定,那么實(shí)際上該謂詞將被剝離出查詢。

當(dāng) PopulationMechanism 的值為 PrepareCommand 時(shí),提供程序編寫者可以使用自定義機(jī)制。有一個(gè) DbMetaDataFactory 的 PrepareCommand 方法,如果它被提供程序編寫者覆蓋,就可以被編碼來使用提供程序選擇的任何自定義語義。這一機(jī)制被用在 SqlClient 中來生成 DataTypes 元數(shù)據(jù)集合。PrepareCommandSqlMetaDataFactory 子類實(shí)現(xiàn)首先從 DataTable 中讀取由 SQL Server 支持的內(nèi)置數(shù)據(jù)類型,如同用其他元數(shù)據(jù)集合一樣;然后,如果數(shù)據(jù)庫是 SQL Server 2005 的話,使用自定義邏輯來將用戶定義的類型添加到集合中。(注:SQL Server 2005 可以將 .NET 類作為用戶定義的類型公開。更多信息請(qǐng)參閱 A First Look at SQL Server 2005 for Developers 的第 5 章。)

返回頁首

用戶自定義

除了提供程序自定義機(jī)制外,也有允許程序員在每個(gè)應(yīng)用程序基礎(chǔ)上自定義架構(gòu)信息的掛鉤!在加載嵌入資源之前,DbConnectionFactory CreateMetaDataFactory 將參考應(yīng)用程序配置文件。每個(gè)提供程序都可以用任何它選擇的方法實(shí)現(xiàn) CreateMetaDataFactory 來為其 DbMetaDataFactory 獲取 XML 流,但是那 4 個(gè) Microsoft 提供程序遵循一個(gè)公共模式。每個(gè) Microsoft 提供程序?qū)⒉檎乙粋€(gè)按提供程序本身命名的應(yīng)用程序配置設(shè)置(如 system.data.sqlclient)。在這個(gè)設(shè)置元素中您可以添加或刪除名值對(duì)。DbMetaDataFactory 查找一個(gè)名稱“MetaDataXml”。與特殊名稱對(duì)應(yīng)的值是一個(gè)文件的名稱。這是一個(gè)簡單的文件名 — 這個(gè)文件必須存在于 .NET 安裝位置的 CONFIG 子目錄中。這是 machine.config 和安全配置設(shè)置所在的目錄。這個(gè)文件必須包含整個(gè)的架構(gòu)配置信息集,而不僅僅是那些更改。

出于多個(gè)原因,對(duì)于支持此機(jī)制的提供程序,您可以使用這個(gè)機(jī)制。例如,您可以更改 OracleClient 提供程序中的架構(gòu)查詢來使用“USER”目錄視圖而不是“ALL”目錄視圖。因?yàn)椤癠SER”視圖不包含關(guān)于內(nèi)部數(shù)據(jù)庫表的信息,例如,表列表將會(huì)短很多并且更易于使用。另一個(gè)示例可能包括為所有的 .NET 數(shù)據(jù)提供程序編碼輸出元數(shù)據(jù) XML 文件,這提供給您一致的標(biāo)準(zhǔn)元數(shù)據(jù)集,該元數(shù)據(jù)集可能正好符合 SQL-99 INFORMATION_SCHEMA 視圖。這可能恰恰適合您的應(yīng)用程序。

一個(gè)更具體的例子是,如果我想要公開 SQL Server 2005 中關(guān)于 SQL Server Service Broker 的元數(shù)據(jù)集合的信息。這些集合可以包括 QUEUE、SERVICE、CONTRACT 和消息類型。我會(huì)從嵌入的 XML 資源文件開始并用我的新集合上的信息修飾它。如果這個(gè)文件的名稱是 SQLBrokerAware.xml,我會(huì)安裝這個(gè)文件,我的應(yīng)用程序配置文件將為如下所示:

<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.data.sqlclient> <settings> <add name="MetaDataXml" value="SQLBrokerAware.xml"></add> </settings> </system.data.sqlclient> </configuration> 

這就是所有的步驟。使用這個(gè)設(shè)置,我可以編寫代碼 — 在其中 Service Broker 元數(shù)據(jù)是可用于客戶端的內(nèi)置元數(shù)據(jù)的組成部分。對(duì)所有隊(duì)列來說,代碼可能如下所示:

using (SqlConnection conn = new SqlConnection(connstring))
{conn.Open();// this includes Service Broker metadata collectionsTable t = conn.GetSchema(DbMetaDataCollectionNames.MetaDataCollections);// get all the queues in my databaseTable queues = conn.GetSchema("Queues");
}

真是非常酷!本文包含一個(gè)添加 Service Broker 元數(shù)據(jù)的代碼示例。盡管這是一個(gè)非常強(qiáng)大的功能,它還是有可能被濫用的。請(qǐng)記住您需要將元數(shù)據(jù) XML 文件分發(fā)到每個(gè)使用它的應(yīng)用程序,并說服系統(tǒng)管理員為您將其安裝在 CONFIG 目錄中。而且您需要用發(fā)布的提供程序的每個(gè)新版本來維護(hù)它。因?yàn)槭褂靡话阍獢?shù)據(jù) API 的理由之一是可擁有跨數(shù)據(jù)庫和應(yīng)用程序的一致元數(shù)據(jù),所以這個(gè)功能不應(yīng)被無故使用。還需注意此時(shí)您不能提供 PrepareCommand 的自定義實(shí)現(xiàn)。

關(guān)于自定義的最后要注意的,您可能已經(jīng)猜到了,自定義和資源對(duì)于 OLE DB 和 ODBC 的橋提供程序的使用是不同的。當(dāng)您使用這些提供程序時(shí),默認(rèn)的 Odbc 或 OleDb XML 資源文件被使用,然后您不僅可以自定義主要的 Odbc 或 OleDb 架構(gòu)行為,而且可以在每個(gè)提供程序基礎(chǔ)上自定義行為。如果您想要指定自己的提供程序或者驅(qū)動(dòng)程序,在添加/刪除設(shè)置子元素中使用的名稱屬性不能是 MetaDataXml,而應(yīng)該是 [providershortname]:MetaDataXml。如果您想讓您的文件成為 OleDb 或 Odbc 數(shù)據(jù)提供程序的默認(rèn)文件,您甚至可以指定 defaultMetaDataXml 的名稱。

返回頁首

小結(jié):元數(shù)據(jù)支持的最終部分

在結(jié)束前,我只想說說其他兩個(gè)不是通過 DbConnection.GetSchema 公開的元數(shù)據(jù)擴(kuò)展。 DbCommandBuilder 包含兩個(gè)屬性,QuoteIdentifierUnquoteIdentifier,它們?cè)试S您在由 CommandBuilder 生成的命令中自定義標(biāo)識(shí)符。舉個(gè)例子,根據(jù)您的會(huì)話設(shè)置,在 SQL Server 中您可以使用雙引號(hào) (") 或括號(hào)('[' 和 ']')來引用標(biāo)識(shí)符。最后,在 System.Data.Sql 命名空間中的 SqlMetaData 類被用于公開 SQL Server DataReader 中的元數(shù)據(jù)并允許您在 SqlCommand 使用的 Parameters 中設(shè)置這個(gè)元數(shù)據(jù)。雖然不是任何地方在細(xì)節(jié)上都非常接近,但是這個(gè)元數(shù)據(jù)在概念上與在 DataTypes 元數(shù)據(jù)集合中公開的元數(shù)據(jù)相似。SqlMetaData 對(duì) SqlClient 數(shù)據(jù)提供程序和 SQL Server 2005 包括的 in-database SqlServer 數(shù)據(jù)提供程序都是適用的。SqlMetaData 增大了當(dāng)前通過 SqlDataReader.GetSchemaTable() 方法公開的行集合元數(shù)據(jù)。

此時(shí)您很可能同意 ADO.NET 2.0 元數(shù)據(jù)基礎(chǔ)結(jié)構(gòu)是您所見過的最強(qiáng)大、靈活和可自定義的結(jié)構(gòu)。它將 ADO.NET 發(fā)展成為一個(gè)完全面向?qū)ο蟮臄?shù)據(jù)庫 API。工具供應(yīng)商、提供程序編寫者和 Visual Studio 數(shù)據(jù)工具用戶將會(huì)高興地在街上跳舞 — 我們那里見。

Bob Beauchemin,DevelopMentor 的講師、課程作者和數(shù)據(jù)庫課程聯(lián)絡(luò)員。作為以數(shù)據(jù)為中心的分布式系統(tǒng)的架構(gòu)師、程序員和管理員,他有超過 25 年的經(jīng)驗(yàn)。他一直為 Microsoft Systems Journal 和 SQL Server Magazine 等雜志撰寫 ADO.NET、OLE DB 和 SQL Server 方面的文章,并且是 A First Look at SQL Server 2005 for DevelopersEssential ADO.NET 的作者。

轉(zhuǎn)到原英文頁面

總結(jié)

以上是生活随笔為你收集整理的ADO.NET 2.0 中的架构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。