熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

在 ADO.NET2.0 中對於從您的數據源訪問元數據

2013-11-13 09:44:19  來源: .NET編程 

  深入了解新的公共元數據
  在我的前一篇文章我指出 Visual Studio 服務器資源管理器現在使用一個包含了 NET 數據提供程序(而不是 OLE DB 提供程序)列表的對話框來提示連接信息當您確定一個連接字符串並添加數據連接時每個數據連接也顯示一個關於通過連接直接可見的數據庫對象(如表視圖和存儲過程)的信息的樹形結構但這些信息來自哪裡呢?難道是 Visual Studio 僅為某些數據提供程序硬編碼來生成這個信息而假如我編寫我自己的數據提供程序或者從第三方購買一個的時候就留給我一個空節點?不在 Visual Studio 中並不是這樣由於 ADONET 中的新架構 API所有這些有用的信息都將提供給您我不知道這是否是 Visual Studio 做到它的方法但是這裡就是使用新的 API 來獲得一個數據庫中的表的列表的代碼
  
  // uses a ADONET named connection string in config file
  // uses ADONET ProviderFactory and base classes
  // see previous article
  public static void GetListOfTables(string connectstring_name)
  {
  ConnectionStringSettings s =
  ConfigurationSettingsConnectionStrings[connectstring_name];
  DbProviderFactory f = DbProviderFactoriesGetFactory(sProviderName);
  using (DbConnection conn = fCreateConnection())
  {
  connConnectionString = sConnectionString;
  connOpen();
  
  DataTable t = connGetSchema(Tables);
  tWriteXml(tablesxml);
  }
  }
  
  究竟誰需要元數據?
  元數據是每個數據訪問 API 的一部分盡管元數據的主要使用者是像 Visual Studio 這樣的工具或者像 DeKlarit 這樣的代碼生成器但是它們並不是惟一的使用者應用程序包設計師可能允許最終用戶通過向現有的表添加新表或新列來自定義一個應用程序當最終用戶如此改變了數據庫架構時一個通用查詢和修改工具可以在維護備份和其他應用程序函數中使用元數據來包含用戶的新表就像它們是應用程序附帶的內置表一樣程序員可以使用元數據來編寫他們自己的派生自 SystemDataCommonDbCommandBuilder的自定義類並為使用 DataSet 創建插入更新和刪除命令多數據庫應用程序(即設計為在用戶選擇的數據庫上運行的應用程序)的構建者可以盡可能多地使用元數據來維護公共代碼庫在需要時優化數據訪問代碼
  
  通過一般元數據 API 來公開元數據要比讓每個使用者使用特定於數據庫的 API 要好這樣工具編寫人員可以維護一個可管理性更好的代碼庫這樣的 API 還必須是非常靈活的因為在編寫一般 API 來公開元數據時有四個障礙需要考慮
  
  元數據集合和信息在數據庫間是有差別的例如SQL Server 用戶可能想要公開一個鏈接服務器的集合但是 Oracle 用戶可能對關於 Oracle 序列的信息感興趣
  
  不僅在不同的數據庫產品中而且即使在相同數據庫的不同版本中存儲公共數據庫元數據的基礎系統表都是不同的例如SQL Server 使用在一個sys架構下的新表(例如systables)公開它的元數據而 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 特定的列到每個行中ADONET 提供了一個甚至更強大更靈活的機制來公開元數據
  
  我能得到什麼樣的元數據?
  ADONET 允許提供程序編寫者公開 種不同類型的元數據這些主要的元數據 — 元數據集合類別 — 在 SystemDataCommonDbMetaDataCollectionNames 類中被枚舉出來
  
  &#; MetaDataCollections — 可用元數據集合的列表
  
  &#; Restrictions — 對於每個元數據集合存在一批可以用於限制被請求的架構信息范圍的限定符
  
  &#; DataSourceInformation — 關於數據提供程序引用的數據庫實例的信息
  
  &#; DataTypes — 一組關於數據庫支持的每個數據類型的信息
  
  &#; ReservedWords — 適用於該種數據庫查詢語言的保留字通常查詢語言等同於一種 SQL 的方言
  
  MetaDataCollections 是 INFORMATION_SCHEMA 集合的名稱主鍵但是如果使用 DbConnectionGetSchema這些元數據類別也被認為是元數據這意味著在代碼方面來說是這樣這些集合可以像普通的元數據一樣被獲得
  
  // gets information about database Views
  Table t = connGetSchema(Views);
  // gets information about collections exposed by this provider
  // this includes the five metacollections described above
  Table t = connGetSchema(DbMetaDataCollectionNamesMetaDataCollections);
  // gets information about the Restrictions metacollection
  Table t = connGetSchema(DbMetaDataCollectionNamesRestrictions);
  // No argument overload is same as asking for MetaDataCollections
  Table t = connGetSchema();
  
   個元數據集合中的 個值得進一步解釋
  
  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 是使用一個重載的 DbConnectionGetSchema 指定的這些限制被指定為一個數組您可以將一個數組指定為和整個限制集合或者一個子集數組一樣大因為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 = connGetSchema(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 = connGetSchema(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
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.