複雜型別
WCF RIA Services 的複雜型別支援提供將一組實體屬性封裝成單一 (複雜) 屬性的方法。當實體包含特定的相關屬性子集時,複雜型別可以用來簡化實體。複雜型別也可供另一個 (不同) 共用相同屬性子集的實體重複使用。複雜型別的常見範例是 Address
,它會將指定地址所需的實體屬性收集在一起。在這類 Address
型別中的屬性集可以包含,例如 StreetAddress
、City
、StateProvince
、PostalCode
和 Country
實體屬性。這個複雜型別可供兩個 Customer
和 Contact
實體使用,前提是它們各自共用這個屬性集。因此一旦定義後,自訂 Address
型別可在其他實體中做為實體屬性使用。
複雜型別是範本,用來在實體型別或其他複雜型別上定義豐富、結構化屬性,因為複雜型別可以包含也是複雜型別的屬性。複雜型別必須指定在其命名空間內唯一的名稱,而且 (選擇性) 包含一個或多個屬性形式的資料。複雜型別只能做為實體型別或其他複雜型別的屬性,因為它們沒有識別,因此無法獨立存在。複雜型別是真正的型別,因此可以在程式碼中具現化及使用,但不像實體型別,它們無法直接查詢或保存到資料庫。複雜型別與實體的另一個差異在於它們無法參與關聯。因此導覽屬性不能在複雜型別上定義,但可以在實體型別上定義。
WCF RIA Services V1.0 SP1 中已加入非實體複雜型別的支援。特別是,支援衍生自 ComplexObject 基底類別之複雜型別的程式碼產生。對產生用戶端 Proxy 的支援與對 RIA Services 實體的支援一樣豐富。此外,也提供中繼資料支援 (相當於實體支援),以及深層驗證、變更追蹤、編輯工作階段和複雜型別參數的支援。這表示自訂型別 (例如 Address
) 現在不只是實體屬性,同時也可以做為網域服務方法的參數或傳回值。
定義及表示複雜型別
本節描述如何使用實體資料模型 (EDM) 設計工具,將實體型別的一組實體屬性封裝成複雜型別。實體資料模型 (EDM) 會使用名為概念結構定義語言 (CSDL) 的網域特定語言 (DSL) 來定義概念模型。設計工具背後、CSDL 中複雜型別的 XML 表示會在此檢驗。
本主題假設您已完成逐步解說:建立 RIA Services 方案,或有相等的知識和現有的 RIA Services 方案可用。
使用設計工具建立複雜型別
開啟取自逐步解說:建立 RIA Services 方案中的 RIAServicesExample 方案,然後在 Entity Framework Designer 中開啟 AdventureWorksModel.edmx 檔案 (預設會開啟)。
從
Address
實體選取下列屬性:AddressLine1
、AddressLine2
、City
、StateProvince
、CountryRegion
和PostalCode
。以滑鼠右鍵按一下其中一個屬性,然後選取 [重構至新的複雜型別]。這會造成模型瀏覽器開啟,其中剛建立、預設名為 ComplexType1 的複雜型別會出現在 AdventureWorksModel.edmx 的 ComplexTypes 資料夾中。模型瀏覽器中所指定的名稱實際上是新 ComplexProperty 型別。這個新複雜屬性所封裝的子屬性現在會顯示在模型瀏覽器中。
選取模型瀏覽器中的
ComplexType1
,並將它變更為MailAddress
。它現在是新 ComplexProperty 型別,可藉由選取Address
實體中的 ComplexProperty,並注意 [屬性] 視窗中的該型別,加以驗證。在 [屬性] 視窗中,將新
MailAddress
型別的 [名稱] 變更為 MailAddress。請注意,這個新名稱現在也會顯示在設計工具中。選取設計工具中的
MailAddress
,按一下滑鼠右鍵並選取 [資料表對應] 以存取 [對應詳細資料] 資料表。這個資料表指出屬性對應至資料庫中的資料表資料行的方式。
複雜型別的 XML 表示
RIA Services 使用概念結構定義語言 (CSDL) 來指定資料模型。CSDL 是 XML 架構語言,描述組成資料驅動應用程式之概念模型的實體、關聯性和函式。新 MailAddress
型別的規格是在 XML 的 CSDL 區段中。
若要存取這個型別,請在 [方案總管] 中選取 AdventureWorksModel.edmx,按一下滑鼠右鍵並選取 [開啟方式],然後選擇 [XML (文字) 編輯器]。Visual Studio 2010 必須關閉資料模型的設計檢視,才能開啟 XML 表示,所以請選取 [是] 核准這個動作。請注意,新的 MailAddress
屬性是在 <EntityType Name=”Address”>
項目內指定:
<Property Name="MailAddress" Type="AdventureWorksLTModel.MailAddress" Nullable="false" />
MailAddress
屬性是在自己的項目區段中定義 (如下所示),其中也會定義關聯。
<ComplexType Name="MailAddress">
<Property Type="String" Name="AddressLine1" Nullable="false" MaxLength="60" FixedLength="false" Unicode="true" />
<Property Type="String" Name="AddressLine2" MaxLength="60" FixedLength="false" Unicode="true" />
<Property Type="String" Name="City" Nullable="false" MaxLength="30" FixedLength="false" Unicode="true" />
<Property Type="String" Name="StateProvince" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Type="String" Name="CountryRegion" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
<Property Type="String" Name="PostalCode" Nullable="false" MaxLength="15" FixedLength="false" Unicode="true" />
</ComplexType>
請注意,<ComplexType>
項目沒有 <Key>
項目,因為後者存在於 <EntityType>
項目。
在另一個實體中重複使用複雜型別
如果有 Manufacturer
實體型別包含一組相同的地址屬性,就可以將這些屬性封裝在複雜 MailAddress
型別中。使用 [重構至新的複雜型別],就如同用來建立複雜型別一樣,然後在 [屬性] 視窗中變更型別和名稱。欄位會指回其個別的實體。例如,Address
實體的 MailAddress
所用的 City
欄位會對應至 Address.City
,而 Manufacturer
實體型別的這個欄位會對應至 Manufacturer.City
。使用 [對應詳細資料] 資料表以確定屬性對應至資料庫中的正確資料行。