[原創]談談WCF中的Data Contract(3):WCF Data Contract對Collection & Dictionary的支持

作者: Artech  來源: 博客園  發布時間: 2008-08-14 10:05  閱讀: 2393 次  推薦: 0   原文鏈接   [收藏]  
摘要:在本篇文章上一部分Order Processing的例子中,我們看到原本已Collection形式定義的DetailList屬性(public IList DetailList)

在本篇文章上一部分Order Processing的例子中,我們看到原本已Collection形式定義的DetailList屬性(public IList<TDetail> DetailList),在Data Contract中卻以Array的方式體現(public OrderDetail[] DetailList)。我們現在就來詳細地討論一下基于Collection & Dictionary Data Contract

Data Contract for Collection

我們照例用例子來說明問題,在這里我們創建一個批量處理
OrderService,于是我們創建了一個OrderCollection Type:

 

namespace Artech.SpecialDataContract.Contract
{
    [DataContract]
    
public class Order
    
{
        [DataMember]
        
public Guid OrderID
        
getset; }

        [DataMember]
        
public DateTime OrderDate
        
getset; }
    }


    
public class OrderCollection : List<Order>
    {

    }

}

下面是Service Contract的定義:

 

namespace Artech.SpecialDataContract.Contract
{
    [ServiceContract]
    
public interface IOrderManager
    
{
        [OperationContract(Name 
= "ProcessWithCollection")]
        
void Process(OrderCollection orders);
}

面是OrderCollection XSD中的呈現:

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/Artech.SpecialDataContract.Contract"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.datacontract.org/2004/07/Artech.SpecialDataContract.Contract"
    xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/">
  <xs:import schemaLocation="http://artech/Artech.SpecialDataContract/OrderManagerService.svc?xsd=xsd1"
          namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
  <xs:complexType name="ArrayOfOrder">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="Order" nillable="true" type="tns:Order" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="ArrayOfOrder" nillable="true" type="tns:ArrayOfOrder"/>
  <xs:complexType
name="Order">
    <xs:sequence>
      <xs:element minOccurs="0" name="OrderDate" type="xs:dateTime"/>
      <xs:element
minOccurs="0" name="OrderID" type="ser:guid"/>
    </xs:sequence>
  </xs:complexType>
  <xs:element
name="Order" nillable="true" type="tns:Order"/>
</xs:schema>

加上通過Add Service Reference默認生成的Class,我們可以很清楚地看出Collection是以Array的形式呈現的(Artech.SpecialDataContract.Client.OrderManagerService.Order[] orders):

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel""3.0.0.0")]
    [System.ServiceModel.ServiceContractAttribute(ConfigurationName
="OrderManagerService.IOrderManager")]
    
public interface IOrderManager 
        [System.ServiceModel.OperationContractAttribute(Action
="http://tempuri.org/IOrderManager/ProcessWithCollection", ReplyAction="http://tempuri.org/IOrderManager/ProcessWithCollectionResponse")]
        
void ProcessWithCollection(Artech.SpecialDataContract.Client.OrderManagerService.Order[] orders);
}

因為Array相對很Common的數據類型,基本上所有的廠商均提供了對Array的支持,這也是WCF在通過Add Service Reference生成Client端代碼的時候,會生成Array的原因。不過并不是我們只有唯一的選擇,事實上VS為此提供了擴展,允許我們對于基于Collection Data Contract生成我們需要的各種類型,我們只需要在Add Service Reference的時候選擇“Configure Service Reference”進行相應的配置:

通過上面的截圖,我們發現在Collection Type一項我們有若干選項,我們可以選擇我們希望生成的數據類型:ArrayArrayListLinkedListGeneric ListCollectionBindingList 

Data Contract for Dictionary

前面的內容,我們分別討論了基于GenericCollectionData Contract,接下來,我們來討論最后一個特殊的數據類型的Data ContractDictionary

延續上面的Order Batch Processing的例子,不過我們現在處理的不是一個OrderCollection對象,而是一個Dictionary對象,線面是Service ContractOrder的定義:

namespace Artech.SpecialDataContract.Contract
{
    [ServiceContract]
    
public interface IOrderManager
    
{
        [OperationContract(Name 
= "ProcessWithCollection")]
        
void Process(OrderCollection orders);

        [OperationContract(Name 
= "ProcessWithDictionary")]
        
void Process(IDictionary<Guid, Order> orders);
    }

}

 

    [DataContract]
    
public class Order
    
{
        [DataMember]
        
public Guid OrderID
        
getset; }

        [DataMember]
        
public DateTime OrderDate
        
getset; }
    }

閑話少說,我們來看XSD

<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/">
  <xs:import schemaLocation="http://artech/Artech.SpecialDataContract/OrderManagerService.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
  <xs:import schemaLocation="http://artech/Artech.SpecialDataContract/OrderManagerService.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/Artech.SpecialDataContract.Contract"/>
  <xs:complexType name="ArrayOfKeyValueOfguidOrder_SkVQi6O3">
    <xs:annotation>
      <xs:appinfo>
        <IsDictionary xmlns="http://schemas.microsoft.com/2003/10/Serialization/">true</IsDictionary>
      </xs:appinfo>
    </xs:annotation>
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="KeyValueOfguidOrder_SkVQi6O3">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="Key" type="ser:guid"/>
            <xs:element name="Value" nillable="true" type="q1:Order" xmlns:q1="http://schemas.datacontract.org/2004/07/Artech.SpecialDataContract.Contract"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
  <xs:element name="ArrayOfKeyValueOfguidOrder_SkVQi6O3" nillable="true" type="tns:ArrayOfKeyValueOfguidOrder_SkVQi6O3"/>
</xs:schema>

Data Contract的名稱為ArrayOfKeyValueOfguidOrder_SkVQi6O3=ArrayOfKeyValueOf+guidKey的類型)+OrderValue+_SkVQi6O3Hash Value)。從該XSD的結構我們不難看出,只是一個數組,每個元素為Key-Value pair

我們照例看看通過Add Service Reference方式生成的Clientcode中的對應的定義:

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel""3.0.0.0")]
    [System.ServiceModel.ServiceContractAttribute(ConfigurationName
="OrderManagerService.IOrderManager")]
    
public interface IOrderManager {               
        [System.ServiceModel.OperationContractAttribute(Action
="http://tempuri.org/IOrderManager/ProcessWithDictionary", ReplyAction="http://tempuri.org/IOrderManager/ProcessWithDictionaryResponse")]
        
void ProcessWithDictionary(System.Collections.Generic.Dictionary<System.Guid, Artech.SpecialDataContract.Client.OrderManagerService.Order> orders);
    }

生成的是一個System.Collections.Generic.Dictionary類型。同Collection一樣,也依然可以有多種選擇:

0
0
 
標簽:WCF
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()