|
數(shù)據(jù)集(DataSet)、數(shù)據(jù)表(DataTable)、集合(Collection)概念是.NET FrameWork里提供數(shù)據(jù)類型,在應(yīng)用程序編程過程中會(huì)經(jīng)常使用其來作為數(shù)據(jù)的載體,屬于ADO.NET的一部分。今天我們WCF分布式開發(fā)步步為贏第8節(jié)的內(nèi)容:使用數(shù)據(jù)集(DataSet)、數(shù)據(jù)表(DataTable)、集合(Collection)傳遞數(shù)據(jù)。本節(jié)內(nèi)容除了介紹幾個(gè)類型概念外的,同樣會(huì)詳細(xì)給出代碼的實(shí)現(xiàn)過程。此外我們會(huì)分析這幾種數(shù)據(jù)類型的優(yōu)勢和缺點(diǎn),以及在面向?qū)ο蟮姆?wù)開發(fā)過程中如何解決這些問題。
【1】數(shù)據(jù)集(DataSet)、數(shù)據(jù)表(DataTable):
我們首先來介紹這兩個(gè)類型的相關(guān)概念,然后在介紹其在WCF應(yīng)用程序開發(fā)中的使用方式。
【1.1】基本概念:
數(shù)據(jù)集(DataSet)、數(shù)據(jù)表(DataTable),相信大家都不回陌生,只要做過ADO.NET進(jìn)行數(shù)據(jù)庫編程的開發(fā)人員來說,都會(huì)使用到這兩個(gè)類。DataSet 是 ADO.NET 結(jié)構(gòu)的主要組件,它是從數(shù)據(jù)源中檢索到的數(shù)據(jù)在內(nèi)存中的緩存。DataSet 由一組 DataTable 對象組成,您可使這些對象與 DataRelation 對象互相關(guān)聯(lián)。您還可通過使用 UniqueConstraint 和 ForeignKeyConstraint 對象在 DataSet 中實(shí)施數(shù)據(jù)完整性。有關(guān)使用 DataSet 對象的詳細(xì)信息,請參見 在 ADO.NET 中使用 DataSet。
盡管 DataTable 對象中包含數(shù)據(jù),但是 DataRelationCollection 允許您遍覽表的層次結(jié)構(gòu)。這些表包含在通過 Tables 屬性訪問的 DataTableCollection 中。當(dāng)訪問 DataTable 對象時(shí),請注意它們是按條件區(qū)分大小寫的。例如,如果一個(gè) DataTable 被命名為“mydatatable”,另一個(gè)被命名為“Mydatatable”,則用于搜索其中一個(gè)表的字符串被認(rèn)為是區(qū)分大小寫的。但是,如果“mydatatable”存在而“Mydatatable”不存在,則認(rèn)為該搜索字符串不區(qū)分大小寫。有關(guān)使用 DataTable 對象的更多信息,請參見 創(chuàng)建 DataTable。
DataSet 可將數(shù)據(jù)和架構(gòu)作為 XML 文檔進(jìn)行讀寫。數(shù)據(jù)和架構(gòu)可通過 HTTP 傳輸,并在支持 XML 的任何平臺(tái)上被任何應(yīng)用程序使用。可使用 WriteXmlSchema 方法將架構(gòu)保存為 XML 架構(gòu),并且可以使用 WriteXml 方法保存架構(gòu)和數(shù)據(jù)。若要讀取既包含架構(gòu)也包含數(shù)據(jù)的 XML 文檔,請使用 ReadXml 方法。
在典型的多層實(shí)現(xiàn)中,用于創(chuàng)建和刷新 DataSet 并依次更新原始數(shù)據(jù)的步驟包括:
- 通過 DataAdapter 使用數(shù)據(jù)源中的數(shù)據(jù)生成和填充 DataSet 中的每個(gè) DataTable。
- 通過添加、更新或刪除 DataRow 對象更改單個(gè) DataTable 對象中的數(shù)據(jù)。
- 調(diào)用 GetChanges 方法以創(chuàng)建只反映對數(shù)據(jù)進(jìn)行的更改的第二個(gè) DataSet。
- 調(diào)用 DataAdapter 的 Update 方法,并將第二個(gè) DataSet 作為參數(shù)傳遞。
- 調(diào)用 Merge 方法將第二個(gè) DataSet 中的更改合并到第一個(gè)中。
- 針對 DataSet 調(diào)用 AcceptChanges。或者,調(diào)用 RejectChanges 以取消更改。
【1.2】
DataSet 和 DataTable 對象從 MarshalByValueComponent 繼承而來,并支持用于遠(yuǎn)程處理的 ISerializable 接口。這些是僅有的可以遠(yuǎn)程處理的 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):
集合也是我們編程開發(fā)中經(jīng)常使用的類型。
【2.1】基本概念:
.NET Framework 提供了用于數(shù)據(jù)存儲(chǔ)和檢索的專用類。這些類提供對堆棧、隊(duì)列、列表和哈希表的支持。大多數(shù)集合類實(shí)現(xiàn)相同的接口,可繼承這些接口來創(chuàng)建適應(yīng)更為專業(yè)的數(shù)據(jù)存儲(chǔ)需要的新集合類。針對 .NET Framework 的 2.0 版和更高版本的應(yīng)用程序應(yīng)當(dāng)使用 System.Collections.Generic 命名空間中的泛型集合類,與對應(yīng)的非泛型類相比,這些類提供了更高的類型安全性和效率。
集合類具有以下特點(diǎn):
集合類定義為 System.Collections 或 System.Collections.Generic 命名空間的一部分。大多數(shù)集合類都派生自 ICollection、IComparer、IEnumerable、IList、IDictionary 和 IDictionaryEnumerator 接口以及它們的等效泛型接口。使用泛型集合類可以提供更高的類型安全性,在某些情況下還可以提供更好的性能,尤其是在存儲(chǔ)值類型時(shí),這些優(yōu)勢會(huì)體現(xiàn)得更明顯。有關(guān)更多信息,請參見泛型的優(yōu)點(diǎn)。
如果將緊密相關(guān)的數(shù)據(jù)組合到一個(gè)集合中,則能夠更有效地處理這些緊密相關(guān)的數(shù)據(jù)。代替編寫不同的代碼來處理每一單獨(dú)的對象,您可以使用相同的調(diào)用代碼來處理一個(gè)集合的所有元素。
若要管理集合,可使用 Array 類和 System.Collections 類添加、移除和修改該集合中的個(gè)別元素或某一范圍內(nèi)的元素。甚至可以將整個(gè)集合復(fù)制到另一個(gè)集合中。某些 Collections 類具有排序功能并且大多數(shù)都有索引。自動(dòng)處理內(nèi)存管理,集合的容量會(huì)根據(jù)需要擴(kuò)展。當(dāng)訪問集合成員時(shí)同步提供線程安全。某些 Collections 類可以生成包裝,這些包裝令集合是只讀的或固定大小的。任何 Collections 類都可以生成自己的枚舉數(shù),該枚舉數(shù)簡化了對元素的循環(huán)訪問。
在 .NET Framework 2.0 版中,泛型集合類提供了新功能,并且使得創(chuàng)建強(qiáng)類型集合變得容易。請參見 System.Collections.Generic 和 System.Collections.ObjectModel 命名空間。
【2.2】集合數(shù)據(jù)契約:
集合有如此強(qiáng)大的特性,這也是我們使用的一個(gè)重要原因。
【3】示例代碼分析:
下面我們來介紹一下使用Dataset、 Datatable和集合類來傳遞數(shù)據(jù)的程序開發(fā)過程。依次介紹服務(wù)契約、宿主、客戶端的開發(fā)配置過程,另外服務(wù)端設(shè)計(jì)了一個(gè)數(shù)據(jù)庫,添加了部分演示數(shù)據(jù),目的是方便Demo。
【3.1】服務(wù)契約:
服務(wù)契約定義了3個(gè)操作契約,分別是使用Dataset、Datatable、List來傳遞數(shù)據(jù),WCF服務(wù)類實(shí)現(xiàn)了接口定義的操作契約,分別返回不同的數(shù)據(jù)結(jié)構(gòu)類型。具體代碼如下:
//ServiceContract 屬性以及 Indigo 使用的所有其他屬性均在 System.ServiceModel 命名空間中定義,//因此本例開頭使用 using 語句來引用該命名空間。
//為了掩飾WCF服務(wù)的操作重載
namespace WCFService
{
//1.服務(wù)契約,操作契約重載
[ServiceContract(Namespace = "http://www.cnblogs.com/frank_xl/")]
interface IWCFService
{
//操作契約,數(shù)據(jù)表
[OperationContract]
System.Data.DataTable GetDataByTable();
//操作契約,數(shù)據(jù)集
[OperationContract]
System.Data.DataSet GetDataByDataSet();
//操作契約,數(shù)據(jù)集合
[OperationContract]
List<User> GetDataByCollection();
}
//2.服務(wù)類,集成接口。實(shí)現(xiàn)契約
public class WCFService : IWCFService
{
//實(shí)現(xiàn)接口定義的方法,DataTable傳遞數(shù)據(jù)
public System.Data.DataTable GetDataByTable()
{
//這里可以定義數(shù)據(jù)持久化操作,訪問數(shù)據(jù)庫等
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;
}
//實(shí)現(xiàn)接口定義的方法,DataSet傳遞數(shù)據(jù)
public System.Data.DataSet GetDataByDataSet()
{
//這里可以定義數(shù)據(jù)持久化操作,訪問數(shù)據(jù)庫等
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;
}
//實(shí)現(xiàn)接口定義的方法,Collection傳遞數(shù)據(jù)
public List<User> GetDataByCollection()
{
//這里可以定義數(shù)據(jù)持久化操作,訪問數(shù)據(jù)庫等
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數(shù)據(jù)契約
[DataContract]
public class User
{
[DataMember]
public string name;
[DataMember]
public int age;
}
}
NET技術(shù):WCF分布式開發(fā)步步為贏(8):使用數(shù)據(jù)集、數(shù)據(jù)表、集合傳遞數(shù)據(jù),轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時(shí)間聯(lián)系我們修改或刪除,多謝。