|
数据集(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):使用数据集、数据表、集合传递数据,转载需保留来源!
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。