|
數據集(DataSet)、數據表(DataTable)、集合(Collection)概念是.NET FrameWork里提供數據類型,在應用程序編程過程中會經常使用其來作為數據的載體,屬于ADO.NET的一部分。今天我們WCF分布式開發步步為贏第8節的內容:使用數據集(DataSet)、數據表(DataTable)、集合(Collection)傳遞數據。本節內容除了介紹幾個類型概念外的,同樣會詳細給出代碼的實現過程。此外我們會分析這幾種數據類型的優勢和缺點,以及在面向對象的服務開發過程中如何解決這些問題。
【1】數據集(DataSet)、數據表(DataTable):
我們首先來介紹這兩個類型的相關概念,然后在介紹其在WCF應用程序開發中的使用方式。
【1.1】基本概念:
數據集(DataSet)、數據表(DataTable),相信大家都不回陌生,只要做過ADO.NET進行數據庫編程的開發人員來說,都會使用到這兩個類。DataSet 是 ADO.NET 結構的主要組件,它是從數據源中檢索到的數據在內存中的緩存。DataSet 由一組 DataTable 對象組成,您可使這些對象與 DataRelation 對象互相關聯。您還可通過使用 UniqueConstraint 和 ForeignKeyConstraint 對象在 DataSet 中實施數據完整性。有關使用 DataSet 對象的詳細信息,請參見 在 ADO.NET 中使用 DataSet。
盡管 DataTable 對象中包含數據,但是 DataRelationCollection 允許您遍覽表的層次結構。這些表包含在通過 Tables 屬性訪問的 DataTableCollection 中。當訪問 DataTable 對象時,請注意它們是按條件區分大小寫的。例如,如果一個 DataTable 被命名為“mydatatable”,另一個被命名為“Mydatatable”,則用于搜索其中一個表的字符串被認為是區分大小寫的。但是,如果“mydatatable”存在而“Mydatatable”不存在,則認為該搜索字符串不區分大小寫。有關使用 DataTable 對象的更多信息,請參見 創建 DataTable。
DataSet 可將數據和架構作為 XML 文檔進行讀寫。數據和架構可通過 HTTP 傳輸,并在支持 XML 的任何平臺上被任何應用程序使用。可使用 WriteXmlSchema 方法將架構保存為 XML 架構,并且可以使用 WriteXml 方法保存架構和數據。若要讀取既包含架構也包含數據的 XML 文檔,請使用 ReadXml 方法。
在典型的多層實現中,用于創建和刷新 DataSet 并依次更新原始數據的步驟包括:
- 通過 DataAdapter 使用數據源中的數據生成和填充 DataSet 中的每個 DataTable。
- 通過添加、更新或刪除 DataRow 對象更改單個 DataTable 對象中的數據。
- 調用 GetChanges 方法以創建只反映對數據進行的更改的第二個 DataSet。
- 調用 DataAdapter 的 Update 方法,并將第二個 DataSet 作為參數傳遞。
- 調用 Merge 方法將第二個 DataSet 中的更改合并到第一個中。
- 針對 DataSet 調用 AcceptChanges。或者,調用 RejectChanges 以取消更改。
【1.2】
DataSet 和 DataTable 對象從 MarshalByValueComponent 繼承而來,并支持用于遠程處理的 ISerializable 接口。這些是僅有的可以遠程處理的 ADO.NET 對象。 我們先來看一下DataSet的定義,使用Reflector工具查看,部分代碼如下:
Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7
f11d50a3a"), DefaultProperty("DataSetName"), XmlSchemaProvider("GetDataSetSc
hema"), ResDescription("DataSetDescr"), XmlRoot("DataSet"), Designer("Microsoft.
VSDesigner.Data.VS.DataSetDesigner, Microsoft.VSDesigner, Version=8.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
public class DataSet : MarshalByValueComponent, IListSource, IXmlSerializable,
ISupportInitializeNotification, ISupportInitialize, ISerializable
{
// Fields
private bool _caseSensitive;
private CultureInfo _culture;
private bool _cultureUserSet;
private string _datasetPrefix;
private object _defaultViewManagerLock;
private readonly int _objectID;
private static int _objectTypeCount;
private SerializationFormat _remotingFormat;
private string dataSetName;
private DataViewManager defaultViewManager;
private bool enforceConstraints;
internal PropertyCollection extendedProperties;
private bool fBoundToDocument;
internal bool fEnableCascading;
internal bool fInitInProgress;

}
【2】集合(Collection):
集合也是我們編程開發中經常使用的類型。
【2.1】基本概念:
.NET Framework 提供了用于數據存儲和檢索的專用類。這些類提供對堆棧、隊列、列表和哈希表的支持。大多數集合類實現相同的接口,可繼承這些接口來創建適應更為專業的數據存儲需要的新集合類。針對 .NET Framework 的 2.0 版和更高版本的應用程序應當使用 System.Collections.Generic 命名空間中的泛型集合類,與對應的非泛型類相比,這些類提供了更高的類型安全性和效率。
集合類具有以下特點:
集合類定義為 System.Collections 或 System.Collections.Generic 命名空間的一部分。大多數集合類都派生自 ICollection、IComparer、IEnumerable、IList、IDictionary 和 IDictionaryEnumerator 接口以及它們的等效泛型接口。使用泛型集合類可以提供更高的類型安全性,在某些情況下還可以提供更好的性能,尤其是在存儲值類型時,這些優勢會體現得更明顯。有關更多信息,請參見泛型的優點。
如果將緊密相關的數據組合到一個集合中,則能夠更有效地處理這些緊密相關的數據。代替編寫不同的代碼來處理每一單獨的對象,您可以使用相同的調用代碼來處理一個集合的所有元素。
若要管理集合,可使用 Array 類和 System.Collections 類添加、移除和修改該集合中的個別元素或某一范圍內的元素。甚至可以將整個集合復制到另一個集合中。某些 Collections 類具有排序功能并且大多數都有索引。自動處理內存管理,集合的容量會根據需要擴展。當訪問集合成員時同步提供線程安全。某些 Collections 類可以生成包裝,這些包裝令集合是只讀的或固定大小的。任何 Collections 類都可以生成自己的枚舉數,該枚舉數簡化了對元素的循環訪問。
在 .NET Framework 2.0 版中,泛型集合類提供了新功能,并且使得創建強類型集合變得容易。請參見 System.Collections.Generic 和 System.Collections.ObjectModel 命名空間。
【2.2】集合數據契約:
集合有如此強大的特性,這也是我們使用的一個重要原因。
【3】示例代碼分析:
下面我們來介紹一下使用Dataset、 Datatable和集合類來傳遞數據的程序開發過程。依次介紹服務契約、宿主、客戶端的開發配置過程,另外服務端設計了一個數據庫,添加了部分演示數據,目的是方便Demo。
【3.1】服務契約:
服務契約定義了3個操作契約,分別是使用Dataset、Datatable、List來傳遞數據,WCF服務類實現了接口定義的操作契約,分別返回不同的數據結構類型。具體代碼如下:
//ServiceContract 屬性以及 Indigo 使用的所有其他屬性均在 System.ServiceModel 命名空間中定義,//因此本例開頭使用 using 語句來引用該命名空間。
//為了掩飾WCF服務的操作重載
namespace WCFService
{
//1.服務契約,操作契約重載
[ServiceContract(Namespace = "http://www.cnblogs.com/frank_xl/")]
interface IWCFService
{
//操作契約,數據表
[OperationContract]
System.Data.DataTable GetDataByTable();
//操作契約,數據集
[OperationContract]
System.Data.DataSet GetDataByDataSet();
//操作契約,數據集合
[OperationContract]
List<User> GetDataByCollection();
}
//2.服務類,集成接口。實現契約
public class WCFService : IWCFService
{
//實現接口定義的方法,DataTable傳遞數據
public System.Data.DataTable GetDataByTable()
{
//這里可以定義數據持久化操作,訪問數據庫等
System.Data.DataSet dataSet = new System.Data.DataSet();
System.Data.DataTable dataTable = null;
SqlConnection sqlConnection = new SqlConnection("Data Source=.//SQL
EXPRESS;AttachDbFilename=|DataDirectory|//Database//DatabaseWCF.mdf;Integrated Security=True;User Instance=True");
try
{
System.Data.SqlClient.SqlDataAdapter sqlDataAdapter = new System.
Data.SqlClient.SqlDataAdapter("SELECT id, name, english_name FROM TableWCF",
sqlConnection);
sqlDataAdapter.Fill(dataSet, "TableWCF");
if (dataSet != null && dataSet.Tables.Count > 0)
{
dataTable = dataSet.Tables[0];
}
}
catch (Exception e)
{
}
finally
{
sqlConnection.Close();
}
Console.WriteLine("Calling WCF Service,Transfer data using DataTable");
return dataTable;
}
//實現接口定義的方法,DataSet傳遞數據
public System.Data.DataSet GetDataByDataSet()
{
//這里可以定義數據持久化操作,訪問數據庫等
System.Data.DataSet dataSet = new System.Data.DataSet();
SqlConnection sqlConnection = new SqlConnection("Data Source=.//SQL
EXPRESS;AttachDbFilename=|DataDirectory|//Database//DatabaseWCF.mdf;Integrated Security=True;User Instance=True");
try
{
System.Data.SqlClient.SqlDataAdapter sqlDataAdapter = new System.
Data.SqlClient.SqlDataAdapter("SELECT id, name, english_name FROM TableWCF",
sqlConnection);
sqlDataAdapter.Fill(dataSet, "TableWCF");
}
catch (Exception e)
{
}
finally
{
sqlConnection.Close();
}
Console.WriteLine("Calling WCF Service,Transfer data using dataSet");
return dataSet;
}
//實現接口定義的方法,Collection傳遞數據
public List<User> GetDataByCollection()
{
//這里可以定義數據持久化操作,訪問數據庫等
List<User> list = new List<User>();
for (int i = 0; i < 10; i++)
{
User user = new User();
user.age = 20+i;
user.name = "Frank Xu Lei:" + i.ToString();
}
Console.WriteLine("Calling WCF Service,Transfer data using Collection");
return list;
}
}
//3數據契約
[DataContract]
public class User
{
[DataMember]
public string name;
[DataMember]
public int age;
}
}
NET技術:WCF分布式開發步步為贏(8):使用數據集、數據表、集合傳遞數據,轉載需保留來源!
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。