首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WCF 資料傳遞:DataSet、DataTable 與集合的序列化特性與跨平台限制

     編輯:關於.NET

WCF 服務常需傳遞結構化資料。DataSet、DataTable 為 ADO.NET 核心類型,List<T> 為通用集合,三者序列化行為差異大,影響跨平台互通性。

DataSet / DataTable 序列化特性

  • 繼承 MarshalByValueComponent,實作 ISerializable、IXmlSerializable,預設可序列化。
  • 優點:Visual Studio 設計工具強型別支援、內建 XML Schema、資料關聯 (DataRelation) 完整保留。
  • 缺點:
    • 序列化後 XML 极其龐大 (含 Schema、DiffGram、關聯、約束),頻寬與解析成本高。
    • 暴露資料庫結構 (資料表名、欄位名、型別、主鍵/外鍵),洩露內部實作細節。
    • 非 .NET 平台 (Java、Python) 解析 DiffGram 困難,違背 SOA 平台無關原則。
    • 資料庫 Schema 變更直接破壞客戶端合約,版本管理困難。

集合 (List<T>) 的特殊封送

  • WCF 針對集合類型提供專屬封送:服務端 List<User> → 客戶端反序列化為 User[] (陣列)。
  • 支援泛型集合:List<T>、Collection<T>、BindingList<T>、Dictionary<K,V> (序列化為 ArrayOfKeyValueOfKV)。
  • 集合元素型別需為資料合約 ([DataContract]) 或可序列化型別。

程式碼示範

[ServiceContract]
public interface IDataService
{
    [OperationContract] DataTable GetByTable();
    [OperationContract] DataSet GetByDataSet();
    [OperationContract] List<User> GetByCollection();
}

[DataContract]
public class User { [DataMember] public string Name; [DataMember] public int Age; }

客戶端 Proxy 產生:
DataTable GetByTable()、DataSet GetByDataSet()、User[] GetByCollection()。注意集合變陣列。

最佳實務建議

  1. 跨平台/公開 API:禁用 DataSet/DataTable,改用 POCO + [DataContract] 定義明確資料合約。
  2. 內部 .NET 專案:可接受 DataSet/DataTable 便利性,但建議封裝於內部合約,勿外洩。
  3. 大量資料:考慮分頁、串流 (Streaming) 或壓縮,避免單次傳輸巨大物件圖。
  4. 集合選擇:服務端用 List<T> 方便操作,客戶端接收陣列 T[] 即可,或透過 CollectionDataContract 自訂集合型別。

總結

DataSet/DataTable 適合 .NET 內部快速原型,但序列化開銷大、耦合資料庫結構、跨平台困難。正式 SOA 系統應採用明確的資料合約 (DataContract) 設計,確保版本演進與異構互通。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved