適合印表機的版本      送出     
按一下以給予評分及指教
Related Articles
ADO.NET 資料服務架構 (ADO.NET Data Services Framework) 的目標,是要建立一個簡單的 REST 架構,以輕鬆地公開及取用以資料為中心的服務。

By Elisa Flasko 以及 Mike Flasko (8 月 2008)
我們要向您介紹 BizTalk Server 2006 R2 中的 EDI 功能,並說明結構描述的建立、文件的對應、EDI 的傳遞與傳輸,以及例外的處理。

By Mark Beckner (8 月 2008)
本文節錄自 Laurence Moroney 即將出版的新書,作者在文中說明了 Silverlight 動畫的基本概念,以及 Expression Blend 所提供的動畫工具。

By Laurence Moroney (8 月 2008)
我們使用 InkPresenter 建置的 Silverlight 2.0 應用程式,可以讓使用者針對預先定義的影像集合塗鴉註解、執行手寫辨識,並將註解和辨識的文字儲存到伺服器端資料庫中。

By Julia Lerman (8 月 2008)
More ...
Popular Articles
Howard Dierking 與 C++ 發明人 Bjarne Stroustrup 對談,內容包括語言的狂熱份子、程式語言的進化,以及展望程式設計的未來。

By Howard Dierking (April 2008)
我們將藉由逐步解說一個效能調查範例,並找出某些範例應用程式中缺乏效率的程式碼,來向您介紹 Visual Studio Profiler。

By Hari Pulapaka and Boris Vidolov (March 2008)
我們使用 InkPresenter 建置的 Silverlight 2.0 應用程式,可以讓使用者針對預先定義的影像集合塗鴉註解、執行手寫辨識,並將註解和辨識的文字儲存到伺服器端資料庫中。

By Julia Lerman (8 月 2008)
OBA 解決方案模式可協助架構設計人員與開發人員建置 Office Business Application (OBA)。本文介紹七種核心 OBA 解決方案模式,並將套用其中一種模式來解決真實世界的問題。

By Steve Fox (March 2008)
More ...
Read the Blog
One of the neat things about XAML is that you can not only declare your objects using an XML syntax, but that you can define transformations to rotate, move, and skew your objects. In the August 2008 issue of MSDN Magazine, in an article adapted from his upcoming book Introducing Microsoft Silverlight ...
Read more!
Microsoft has a long history of introducing new features to shipped products, often under the banner of Power Toys or Power Tools. In the August 2008 issue of MSDN Magazine, Brian Randell takes you on a tour of some useful tools for ...
Read more!
Designing software is often an exercise in managing complexity. You can take steps to limit the complexity of any given class by only assigning it a discrete set of responsibilities, applying a concept known as object role stereotypes. In the August 2008 issue of MSDN Magazine, Jeremy Miller explains ...
Read more!
When you evaluate any new technology, pattern, or strategy, you have to consider how that new piece of the puzzle is going to mesh with your existing application architecture. With the Entity Framework, integration is not a problem. In the July 2008 issue of MSDN Magazine, John Papa demonstrated ...
Read more!
Electronic Document Interchange (EDI) encompasses the largest share of real-world business-to-business commerce—nearly 90 percent of the current market—and is growing rapidly year over year. In the August 2008 issue of MSDN Magazine, Mark Beckner introduces ...
Read more!
Separation of presentation and data is not a new idea, but with the growing popularity of technologies such as AJAX and Silver­light, it has become much more prevalent. ADO.NET Data Services Framework began as a way to help developers looking to expose and consume data via services from their applications.. In the August 2008 issue of MSDN ...
Read more!
More ...
資料服務
使用 SQL Server 資料服務開發功能強大且可擴充的應用程式
David Robinson

本文討論下列主題:
  • SSDS 資料模型
  • 管理實體、容器及授權單位
  • 建立 Web 應用程式範例
  • 類別的序列化與還原序列化
本文使用下列技術:
SQL Server
本專欄是以 SQL Server 資料服務的搶鮮版為基礎。本文包含的所有資訊均有可能變更。
Microsoft 資料平台是由豐富的產品和技術所組成,適用於所有資料型別,從無結構的二進位資料到高度結構化的線上分析處理 (OLAP) Cube 都適用。雖然這些技術適用於您可能碰到的任何應用程式案例,但是在開始撰寫解決方案的程式碼之前,通常需要預先投入可觀的時間和硬體資源。
應用程式開發人員很難預估應用程式在其生命週期中,需要多少儲存體和處理動力。對於初創公司而言,如果公司資金不寬裕,且又欠缺用以評估硬體投資決策的資料,這種情形尤其嚴重。為了減輕預先投資的負擔,Microsoft 最近在功能已經很強大的資料平台上注入了嶄新技術:SQL Server® 資料服務 (SSDS)。
這不像一般傳統套裝軟體,SSDS 是一個功能強大且可隨意擴充的資料服務,它在內部使用已證實為有效的 SQL Server 技術,並且透過符合產業標準的 Web 服務介面來公開其功能。SSDS 提供了易用又有彈性的資料模型,您可以透過開放式、符合產業標準的通訊協定來存取。
不論您是用 Microsoft® .NET Framework、Java 或是其他技術進行開發,都可以使用 SSDS 做為資料存放區。此外,SSDS 的設計目標,就是要讓開發人員能夠快速配置帳戶,並立刻用來進行開發。
SSDS 會提供開發人員一種資料後端,且不受可用磁碟機槽或機架空間的限制。藉由使用 SSDS 做為資料平台,您的應用程式就可以任意使用所需的資料量。不論是需要十億位元組 (Gigabyte, GB) 或是千兆位元組 (Petabyte, PB) 的儲存量,您都只要負擔實際使用的資源。
許多網站與應用程式都具有循環性的存取模式,因此您需要足夠的容量以應付尖峰負載,即使這樣的負載量並不會持續。藉由使用 SSDS 做為資料後端,您就可以將注意力放在應用程式上,而不必放在資料平台容量的規劃上。
我將在本文中介紹如何使用 SSDS 來開發資料解決方案的基本概念。.我一開始會先介紹 SSDS 的資料模型。接著我會展示如何使用 SSDS 建置簡單的線上分類廣告系統,如 [圖 1] 所示,來深入探討開發的詳細資訊。
圖 1 SSDS 所裝載的 Classifieds 應用程式範例 (按一下影像以放大圖片)

SSDS 資料模型
SSDS 提供了有彈性且以實體為基礎的資料模型。這個模型具有三個主要的元素 -- 授權單位 (Authority)、容器 (Container) 及實體 (Entity) -- 這些稱為 ACE 概念 (請參閱 [圖 2])。SSDS 授權單位在關聯式的世界裡,可以與資料庫相關。當您提供授權單位時,SSDS 會為您建立 DNS 名稱,以便讓您存取該授權單位。例如,如果您提供一個稱為 ssdsdemo 的授權單位,就可以依據下列 URI 來存取它:
ssdsdemo.data.beta.mssds.com
[圖 2] 基本的 SSDS 元件
授權單位也是地理位置的單位,這表示建立的 DNS 名稱會對應到裝載資料處的特定 Microsoft 資料中心。如果您建立了兩個授權單位 (americasdemo.data.beta.mssds.com 和 europedemo.data.beta.mssds.com),就個別會與最靠近使用者的資料中心相關聯。
授權單位會包含容器的集合,容器類似於關聯式資料庫中的資料表。關鍵的差別在於您會將結構描述附加到資料庫資料表上,使資料表的所有資料列都同質。SSDS 中的容器並不需要結構描述,如此讓您能夠在一個方便的位置儲存異質性的實體。它只是實體的集合而已。在目前的 SSDS 版本中,所有查詢的範圍都侷限於單一容器。
此時還有一點非常重要,就是每個容器都會置於 SSDS 叢集中的不同節點上。在 SQL Server 中,若要取得額外的效能,您可以將不同的資料表置於不同的磁針上,以盡可能增加讀/寫的速度。在 SSDS 中也十分類似,只是每個容器都是在不同的電腦上。藉由將資料分割到多個容器上並且以多重執行緒來執行要求,即可進一步提高效能,因為讀寫的動作不受單一電腦的侷限。
關於容器的注意事項還有最後一點,亦即雖然每個容器都是置於 SSDS 叢集中的不同節點上,但是資料也會複寫到其他節點上,以供嚴重損壞時修復之用。如果您的容器所在的電腦發生故障,其中一套備份複本就會自動升級,以確保應用程式不會有資料遺失或效能降低的問題。
實體可以類比為關聯式資料庫裡之資料表中的資料列。實體只是名稱/值配對組成的屬性包。這些名稱/值的配對,可以分類為兩種群組:可分辨系統屬性 (Distinguidshed System Property) 以及彈性屬性 (Flexible Property)。
可分辨系統屬性適用於所有實體,其中包括 ID、Kind 及 Version。ID 能夠唯一識別實體。ID 在其所存在的容器內必須是唯一的,但是不同的容器可以擁有具相同 ID 的實體。Kind 會用來將類似的實體放在同一個分類中。實體上沒有附加結構描述,因此屬於相同 Kind 的實體並不能保證有相同的結構。Version 則會用來識別實體的目前版本,這個值在每一項作業之後都會加以更新。
彈性屬性是開發人員儲存應用程式資料的位置。彈性屬性可以支援簡單的型別:字串 (string)、十進位值 (decimal)、布林值 (bool)、日期時間 (datetime) 及二進位值 (binary)。每個彈性屬性都會依前 256 個位元組來建立索引。

建置分類廣告系統
為了展示 SSDS 的功能,並且說明開發經驗的概觀,我會為您逐步說明一個線上分類廣告系統 (即 Contoso Classifieds) 範例的實作。範例中包含兩個不同的應用程式:一個 Windows® Form 應用程式 -- 用以管理系統,以及一個 ASP.NET 應用程式 -- 使用者會瀏覽的主要 Contoso Classifieds 網站。應用程式可以經由 Windows Form 應用程式中的 SOAP 介面,以及透過 ASP.NET 應用程式中的代表性狀態傳輸 (Representational State Transfer,REST) 介面,來存取 SSDS。
當您註冊 SSDS 帳戶時,就會收到使用者名稱和密碼。接下來,您要開始建置授權單位、容器及實體。對於 Contoso Classifieds 來說,我將授權單位設定為 contosoclassifieds,而測試版 SSDS 中的服務 URI 端點是 data.data.beta.mssds.com。
contosoclassifieds 授權單位包含兩個容器:Categories (分類) 與 Cities (城市)。Categories 會包含與 Listing (清單) 分類相關的實體。Cities 會針對系統中所定義的每個城市 (city),各包含一個實體。這些實體只會是城市專屬授權單位的指標。每個城市專屬的授權單位都會針對每個清單分類建立一個容器 (請參閱 [圖 3])。
圖 3 Contoso Classifieds 的元素 (按一下影像以放大圖片)
我採用這種設計有幾項理由。我選擇每個城市都實作一個授權單位,以確保提供授權單位的資料中心,在地理上靠近其所服務的使用者。我選擇為每個清單分類建立一個容器,以簡化查詢模式,且可以將負荷分散到叢集中的多部電腦上 (請記住,容器的範圍會對應到後端叢集中的特定節點)。[圖 4] 顯示 Contoso Classifieds 管理用戶端的使用者介面。
圖 4 Classifieds 應用程式的管理用戶端 (按一下影像以放大圖片)
如前所述,應用程式要使用之任何授權單位、容器及實體的建立,完全由開發人員決定。在應用程式範例中,所有這些工作都包含在 [Perform Initial Setup (執行初始安裝)] 按鈕的按鍵事件中 (完整的程式碼,包括錯誤處裡,都包含在本文的程式碼下載中)。
提供 SSDS 授權單位的方法極為容易。我在本程式碼範例中使用 SitkaSoapServiceClient,我先前曾為其新增服務參考至 SSDS SOAP 介面:
using (SSDSClient.SitkaSoapServiceClient ssdsProxy = 
  new SSDSClient.SitkaSoapServiceClient())
您已經看過授權單位 (Authority) 了,但是 SSDS 範圍 (Scope) 是什麼?Scope 物件係使用於 SSDS 中,以定址 SOAP 服務中的物件,類似於 REST 服務中使用 URI 的方式。
您應該做的第一件事,就是設定服務的使用者名稱和密碼:
ssdsProxy.ClientCredentials.UserName.UserName = 
  txtUserName.Text;
ssdsProxy.ClientCredentials.UserName.Password = 
  txtPassword.Text;
您必須建立授權單位,它是 ACE 模型的最高層級,因此可以先建立空的範圍:
SSDSClient.Scope serviceScope = new SSDSClient.Scope();
然後再建立 Contoso Classifieds Authority。此舉會在系統中存放一般性的組態資訊,
SSDSClient.Authority contosoAuth = 
  new SSDSClient.Authority();
contosoAuth.Id = "contosoclassifieds";
並且將所建立的提交到 SSDS
ssdsProxy.Create(serviceScope, contosoAuth);
建立了主要的 Contoso Classifieds Authority 之後,請將範圍指向它,然後建立容器以存放您將伺服分類廣告的城市,再將建立的容器提交到 SSDS:
serviceScope.AuthorityId = contosoAuth.Id;

SSDSClient.Container citiesContainer = new SSDSClient.Container();
citiesContainer.Id = "Cities";

ssdsProxy.Create(serviceScope, citiesContainer);
建立容器的程序與建立授權單位的程序十分類似。唯一的差別在於您要建立的是 Container 物件而不是 Authority 物件,且您要將範圍更新為指向即將建立之容器的授權單位,而非空的範圍。
針對應用程式中要支援的所有 Header 和 Listing 分類建立容器:
SSDSClient.Container categoriesContainer = 
  new SSDSClient.Container();
categoriesContainer.Id = "Categories";

ssdsProxy.Create(serviceScope, categoriesContainer);
建立授權單位之後,您就可以使用 HTTP 或 HTTPS 將網頁瀏覽器指向它,也可以使用 REST 介面來檢視容器的內容。在設定授權單位時,只要使用 SSDS 所建立的新 DNS 名稱即可。在此案例中,URL 就會是:
http://contosoclassifieds.data.data.beta.mssds.com/v1
將這個 URL 輸入瀏覽器之後,就會提示您進行驗證。驗證成功之後,就會在瀏覽器中看到類似下面的內容:
<s:Authority xmlns:s="http://schemas.microsoft.com/sitka/2008/03/" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:x="http://www.w3.org/2001/XMLSchema">
  <s:Id>contosoclassifieds</s:Id>
  <s:Version>11</s:Id>
</s:Authority>
授權單位名稱會是小寫的,因為 SSDS 會建立授權單位的 DNS 項目,所以您必須遵循 DNS 的命名慣例。
建立容器之後,如果您重新整理瀏覽器,並且以 ?q="" 的形式將空的查詢新增至 URL,就會在 EntitySet 中看見傳回單一 Container 物件。EntitySet 只是實體的集合,這會傳回做為查詢的回應。在完成初始安裝之後,應用程式範例就會建立一個授權單位 (contosoclassifieds) 與兩個容器 (Categories 與 Cities):
<s:EntitySet xmlns:s="http://schemas.microsoft.com/sitka/2008/03/" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:x="http://www.w3.org/2001/XMLSchema">
  <s:Container>
    <s:Id>Categories</s:Id>
    <s:Version>1</s:Id>
  </s:Container>
  <s:Container>
    <s:Id>Cities</s:Id>
    <s:Version>1</s:Id>
  </s:Container>
</s:EntitySet>
初始安裝完成之後,接著就讓我們來新增城市伺服功能。

新增城市
如前所述,Contoso Classifieds 會將每個城市的清單都放入其授權單位之中,此舉能夠讓您選擇裝載它的資料中心 (雖然 SSDS 的 Beta 版目前尚未支援此功能,但是在產品正式發行時,就會支援此功能。)
新增城市的程式碼與初始安裝的程式碼十分類似。使用 SOAP Proxy 來設定認證、建立空的範圍、設定授權單位 ID 以及下達建立的指令:
SSDSClient.Authority cityAuth = 
  new SSDSClient.Authority();
cityAuth.Id = cityAuthorityName;

ssdsProxy.Create(serviceScope, cityAuth);
建立新的城市授權單位之後,還要新增指標實體至主要 contosoclassifieds 授權單位中的 Cities 容器:
serviceScope.AuthorityId = "contosoclassifieds";
serviceScope.ContainerId = "Cities";

//Create the City Entity, and set its properties appropriately
SSDSClient.Entity cityEntity = new SSDSClient.Entity();
cityEntity.Id = cityAuthorityName;
cityEntity.Kind = "CityServed";
cityEntity.Properties = new Dictionary<string, object>();
cityEntity.Properties["AuthorityUri"] = 
  string.Format("{0}.data.data.beta.mssds.com/v1/", cityAuthorityName);
cityEntity.Properties["Name"] = txtCity.Text;

//Issue the create to SSDS
ssdsProxy.Create(serviceScope, cityEntity);
讓我們複習一下。我已建立了主要 contosoclassifieds 授權單位,其中存放了整個系統上的所有資料。在該授權單位中,有一個 Cities 容器,其中具有應用程式要伺服之每個城市的實體。該實體包含了城市的顯示名稱,以及包含所有清單之授權單位的指標。

新增分類
到目前為止,您已新增了授權單位、容器及實體。下一步就是要實作清單分類的功能。若要這麼做,就需要使用 SSDS 的查詢、更新及刪除等功能。
Contoso Classifieds 可支援分類標頭,並在其下包含子分類,以存放使用者實際張貼的內容。如果對此資料使用關聯式模型,那麼通常會針對資料使用標頭/行 (Header/Line) 的模式。然而,SSDS 所使用的彈性實體資料模型,可以讓資料採用您喜歡的任意形狀。在 Contoso Classifieds 應用程式的案例中,我選擇使用單一實體來代表每個分類標頭,以及它的所有子分類 (請參閱 [圖 5])。
圖 5 應用程式使用的實體資料模型 (按一下影像以放大圖片)
請注意,我之所以使用這種模式,只是要顯示實體具有彈性的本質,並展示雖然多個實體都可以有相同的 Kind,但卻不會強迫實體都具有同質性。實體可以採用您喜歡的任意形狀。
解決這種情況的較理想方法,可能是同時有兩個不同的實體 Kind,即 Category 和 Listing Category,並且在所有實體中都使用 CategoryID 的彈性屬性。如此一來,您就可以使用如下的查詢:
from e in entities where e["CategoryID"] ==­    "For Sale" select e
請注意,我說的是彈性屬性。如前所述,容器中的實體必須有獨一無二的 ID,因此您將無法使用可分辨系統屬性 ID。另請注意我所使用的查詢語法。SSDS 會使用類似 LINQ 的查詢語法,對於使用 .NET Framework 的大多數開發人員來說,此語法看起來應該很熟悉。
如果您回去查看 [圖 4] 中所示的管理應用程式,就會發現有一個代表清單分類的樹狀檢視,以及用於新增分類標頭與清單分類的兩個文字方塊。讓我們來深入探討如何實作分類標頭的新增。
就像先前的程式碼一樣,您使用了 SitkaSOAPServiceClient 來設定認證,並且將範圍設定至 contosoclassifieds 授權單位以及 Categories 容器。接下來您只需要建立實體:
SSDSClient.Scope serviceScope = new SSDSClient.Scope();

serviceScope.AuthorityId = "contosoclassifieds";
serviceScope.ContainerId = "Categories";

SSDSClient.Entity categoryHeaderEntity = new SSDSClient.Entity();
categoryHeaderEntity.Id = CategoryID;
categoryHeaderEntity.Kind = "Category";
您也可以新增一個彈性屬性,來包含分類名稱。請注意,此舉只會將單一屬性新增至彈性屬性的集合:
categoryHeaderEntity.Properties = 
  new Dictionary<string, object>();
categoryHeaderEntity.Properties["CategoryName"] = CategoryName;
下一步是要新增清單分類。因為 Contoso Classifieds 會使用單一實體來代表分類標頭裡的整個清單分類集合,所以您必須擷取分類實體、新增額外的清單分類 (會新增為額外的彈性屬性),並且將更新提交至 SSDS。
若要擷取分類實體,請設定範圍以直接指向它,並且呼叫 Get 方法,這會直接擷取實體而不必使用查詢:
SSDSClient.Scope serviceScope = new SSDSClient.Scope();
serviceScope.AuthorityId = "contosoclassifieds";
serviceScope.ContainerId = "Categories";
serviceScope.EntityId = CategoryID;
//Retrieve the Category Entity
SSDSClient.Entity categoryEntity = ssdsProxy.Get(serviceScope);
接下來只要判斷新屬性的索引、將其新增為額外的彈性屬性,並下達更新的指令即可 (請參閱 [圖 6])。

更新與刪除實體
清單分類的更新與新增額外的彈性屬性一樣簡單。對每項更新來說,您必須擷取實體、在本機執行任何更新然後提交更新,以便將更新的實體與範圍一併傳遞至 Update 方法。
首先要將服務範圍設定為主要 contosoclassifieds 授權單位。另外還要將其指向 Categories 容器以及您要更新之分類的實體:
SSDSClient.Scope serviceScope = new SSDSClient.Scope();
serviceScope.AuthorityId = "contosoclassifieds";
serviceScope.ContainerId = "Categories";
serviceScope.EntityId = currentHdrNode.Name;
取得您要更新的實體:
SSDSClient.Entity categoryEntity = ssdsProxy.Get(serviceScope);
接下來您可以重新初始化彈性屬性的集合,重新新增清單分類的所有彈性屬性。或者,您也可以執行迴圈來更新每個彈性屬性,但基於這個實體的結構很簡單,因此重新建立實體反而比較容易,如 [圖 7] 所示。
若要刪除實體或容器,請將 ServiceScope 指向該項目,並且呼叫 SitkaSoapServiceClient 的 Delete 方法。如果它是標頭,請刪除整個實體:
if (m_OldSelectNode.Parent == null) {
  ssdsProxy.Delete(serviceScope);
}
至於其他的實體,請依循更新所做的一樣,亦即重新建立彈性屬性的集合並重新建置,以針對所有節點 (除了已刪除節點以外) 執行新增作業:
SSDSClient.Entity categoryEntity = ssdsProxy.Get(serviceScope);
categoryEntity.Properties = new Dictionary<string, object>();
categoryEntity.Properties["CategoryName"] = CategoryName;

int propCount = 1;

foreach (TreeNode node in entityNode.Nodes) {
  string listingIdPropName = string.Format    ("ListingCategoryID{0}", propCount);
  string listingNamePropName = string.Format    ("ListingCategoryName{0}", propCount);

  if (node.Text != m_OldSelectNode.Text) {
    categoryEntity.Properties[listingIdPropName] = node.Name;
    categoryEntity.Properties[listingNamePropName] = node.Text;

    propCount++;
  }
}
最後,您還要對 SSDS 下達更新的指令,從樹狀檢視中移除該節點:
ssdsProxy.Update(serviceScope, categoryEntity);

tvCategories.Nodes.Remove(m_OldSelectNode);

新增與刪除清單結構描述
目前的 SSDS Beta 版並不支援結構描述。雖然已經有計劃要在未來新增對結構描述的支援,但是在 SSDS 裡自行新增結構描述其實是一件輕易的工作。唯一要注意的是,您必須從應用程式中管理結構描述,因為目前 SSDS 並不會強制使用它。
就 Contoso Classifieds 而言,管理人員應該針對某些清單分類定義自訂的結構描述。您可以在管理用戶端裡定義結構描述,並且稍後在實作網站時使用它。
到目前為止,在同一個容器裡並沒有異質性的實體。因為每個實體都有 Kind 屬性,所以您可以用來將不同的實體型別儲存在同一個容器裡,也可以查詢屬於特定型別 (在此案例中為 Kind) 的實體。雖然 Kind 並沒有相關聯的結構描述合約,但這個機制很容易就可用來集合類似的資料。接下來我要將 Kind 為 ListingSchema 的新實體,新增至 Categories 容器。
新增清單結構描述的對話方塊相當簡單,如 [圖 8] 所示。它可以讓管理人員定義與清單相關聯的其他欄位,以及將某些欄位識別為必要的欄位。稍後我在展示如何實作實際的網站時,會對此做更詳細的說明。
圖 8 自訂清單的結構描述 (按一下影像以放大圖片)
用來新增 ListingSchema 實體的程序與您已看過的相同,只是這回會使用不同的實體 (即 Kind)。新增 ListingSchema 的程式碼如 [圖 9] 所示。在為 For Sale Cars 分類新增清單結構描述之後,請注意到 Categories 容器的內容就會包含兩種不同的實體型別,而且在同一個容器中有完全不同的資料。
涉及管理用戶端的最後部分,就是要在刪除清單分類時,刪除自訂清單結構描述。先前我討論過如何刪除實體與容器,但是當時我知道要刪除之實體或容器的 ID。若要刪除結構描述,就要先下達 LINQ 查詢,以擷取附加到清單分類的所有清單結構描述,再將其刪除。查詢看起來如下所示:
string.Format(@"from e in entities 
  where e.Id == ""{0}"" select e", CategoryID);
此查詢會傳回 ListingSchema 實體的清單,您只要進行刪除即可。整個 DeleteListingSchema 方法會如 [圖 10] 所示。
此刻 Contoso Classifieds 管理用戶端已完成,接著我就可以使用 SSDS 的 REST 介面,繼續實作此網站。

Classifieds Web 應用程式
如前所述,您可以透過其 REST 介面及其 SOAP 介面來存取 SSDS (如我針對 Contoso Classifieds 管理用戶端所做的一樣)。不論您選擇的介面為何,觀念和功能都是相同的,但是使用 REST 時,您需要進行直接的 HTTP (或 HTTPS) 呼叫。
開始之前,請先回顧 [圖 1] 中所示的 Web 應用程式主要介面。其中的樹狀檢視代表清單分類、主要內容區域,以及在應用程式中已設定為支援之所有城市的 Datalist。請查看其中的每一項,我會展示用 SSDS 開發 ASP.NET 應用程式有多麼容易。
如果您查看樹狀檢視的 ASPX 程式碼,就會了解它相當的簡單:
<h3>Groups</h3>
<asp:TreeView ID="TreeView1" runat="server" 
  onselectednodechanged="TreeView1_SelectedNodeChanged">
</asp:TreeView>
關鍵在於程式碼後置 (Code Behind),如 [圖 11] 所示。您應該注意的第一件事,就是 URI 的建置,它是 Categories 容器的指標。因為這項資料並不是城市專屬的,所以我選擇將其儲存在主要的 contosoclassifieds 授權單位中,於 Categories 容器之內。
完成這項作業之後,我接著使用 LINQ 查詢來擷取 Kind 分類的所有實體,然後使用 UriBuilder 物件將它們全部整理在一起,並新增必要的 HTTP 逸出字元。接下來,我再呼叫 GetHTTPWebRequest 方法,並傳入逸出的 URI 以及 NetworkCredential 物件,其中包含 SSDS 使用者名稱和密碼。GetHTTPWebRequest 會傳回 EntitySet 的字串表示,其中包含符合查詢述詞的所有 Entities (實體)。
GetHTTPWebRequest 是一種靜態的 Helper 方法,可用來隱藏部分 HTTP 細節:
WebRequest request = 
  HttpWebRequest.Create(Uri.EscapeUriString(serviceUri));
request.Credentials = requestCredential;
request.Method = "GET";
request.ContentType = XmlContentType;

// Get the response and read it in to a string.
using (HttpWebResponse response = 
  (HttpWebResponse)request.GetResponse()) {

  return ReadResponse(response);
}
接下來只需要建立新的 WebRequest 物件、設定要傳遞給它的 Credentials (認證)、設定合適的 HTTP 指令動詞、將 ContentType 設定為 XML,然後呼叫 GetResponse 方法。接著我呼叫 ReadResponse,這是另一個靜態的 Helper 方法,且會使用資料流讀取器來讀取 HTTPResponse 並將其傳回給呼叫者。然後程式碼後置 (Code Behind) 就會取得傳回的 XML、將其載入 XmlDocument,並用來載入樹狀檢視。

類別的還原序列化
到目前為止,程式碼只是以手動的方式操作 XML,但其實可以輕易地將實體還原序列化成類別。在此案例中,應用程式會使用 CityServed 類別。
基底 Entity 類別是相當基本的類別。此類別同時包含了 ID 和 Version 的屬性 (Property),它們適用於所有實體。其中還包含一些必要的屬性 (Attribute),使類別能夠序列化。
CityServed 會從基底 Entity 類別繼承,如 [圖 12] 所示。泛型 Query 方法會傳回型別為 CityServed 實體的清單:
foreach (CityServed i in HTTPHelper.Query<CityServed>(
  appDataUri, query, new System.Net.NetworkCredential(
  conSSDSUsername, conSSDSPassword)))
Query 方法 (包含在本文的程式碼下載中) 只是一個泛型靜態 Helper 方法,它會呼叫我們先前所使用的 GetHTTPWebRequest 方法。Serialize 與 Deserialize 方法如 [圖 13] 所示。結合 Query 方法與 Serialize 及 Deserialize 方法,就可以讓您使用強型別的 .NET 物件,並且將它們儲存到 SSDS 中。

使用自訂的清單結構描述
如前所述,SSDS 實體很有彈性,這表示每個實體都可以採用您要的任意形狀。例如,Contoso Classifieds 管理用戶端可以讓您將結構描述新增至清單分類。您也可以從 SSDS 擷取自訂結構描述,並動態地建立可用來新增清單至系統的項目表單。
第一步是要建立具有四個資料行的 DataTable:Field、Value、DataType 及 Required。這個資料表會存放管理人員針對清單所定義的欄位。接下來我會進行查詢,以了解是否已針對清單定義了自訂結構描述:
string appDataUri = string.Format(@"http://{0}.{1}{2}", 
  conSSDSAuthName, conSSDSUri, "Categories");
string query = string.Format(
  @"from e in entities where e[""ListingID""] == ""{0}"" select e", 
  listingCategoryID);

UriBuilder newUri = new UriBuilder(appDataUri);
newUri.Query = String.Format("q='{0}'", Uri.EscapeDataString(query));

string xmlResults = HTTPHelper.GetHTTPWebRequest(newUri.Uri.ToString(), 
  new System.Net.NetworkCredential(conSSDSUsername, conSSDSPassword));

XmlDocument categoriesDoc = new XmlDocument();
categoriesDoc.LoadXml(xmlResults);
XmlNodeList nodeList = categoriesDoc.SelectNodes("//ListingSchema");
然後我就可以將傳回的 XML 載入 DataTable 中,並將其繫結至 DataList。
在 REST 介面中,您必須建置實體的 XML 表示,並下達 HTTP POST 指令至想要插入實體的容器。實體的建置很容易 -- 您只要使用未定案實體並迴圈處理每個欄位,將其新增做為 XML 文件中的節點即可:
foreach (DataListItem fieldItem in dlAddFields.Items) {
  Label lblField = (Label)fieldItem.FindControl("lblAddField");
  TextBox tbItem = (TextBox)fieldItem.FindControl("txtAddValue");
  Label lblFieldType = (Label)fieldItem.FindControl("lblAddFieldType");
  entity = entity + String.Format(
    @" <{0} xsi:type='x:{1}'>{2}</{0}>", lblField.Text.Replace(" ", ""), 
    lblFieldType.Text, tbItem.Text);
}
最後則是要建置指向您希望執行 POST 之容器的 URI,並下達 POST 指令:
string serviceUri = string.Format(@"http://{0}.{1}{2}", 
  postingAuthority, conSSDSUri, postingContainer);

HTTPHelper.PostHTTPWebRequest(serviceUri, entity, 
  new System.Net.NetworkCredential(
  conSSDSUsername, conSSDSPassword));

展望未來
使用 SSDS 進行開發非常容易。我要再次強調的是,SSDS 是建置於健全的 SQL Server 與 Windows Server® 技術之上。雖然此產品的團隊選擇在 SSDS 的 Beta 版中只提供有限的功能集,但未來還會有更多、更豐富的功能。目前可用的功能子集已經可以用來解決客戶需要處理的許多情況。
此外,您也可以預期 SSDS 的支援將會持續加入 SQL Server 套裝產品及工具中。所以,不論您是使用 C#、Visual Basic®、Java、Ruby、甚至是 Microsoft Office Access® 的開發人員,SSDS 都會是儲存應用程式資料的理想位置,因為它可以支援開放式的通訊協定。若要進一步了解詳細資訊,請造訪 SSDS 網站,網址是