在上篇Blog中介绍了如何定义一个与DataRow相结合的数据类,那么本篇将介绍如何定义一个与 DataTable对应的数据集合。
在DotNet中提供了一个CollectionBase作为我们定义强类型的数据集合的抽象类,在DotNet1.1中要定 义一个强类型的数据集合就必须为每一种数据类定义一个对应的数据集合,在2.0中增加了泛型的功能后 ,这个问题得到了解决。又由于在目前的Ibatisnet版本中还不支持泛型的功能,所以数据集合可以选择 从ArrayList或CollectionBase继承下来。但是不管是ArrayList还是CollectionBase都不支持序列化,也 是他们都有没有Serializable属性,那么实现的数据集合也将无法实现序列化,所以这边选择直接实现 IList接口,内部再实例化一个ArrayList做为数据容器。类的定义如下:
public class ObjectList : IList, ISerializable{}
还有一需要解决的问题是,数据类如何与DataTable对应起来呢?在数据类定义一个DataTable的属性 和内部变量,做为存储数据的容器。
1private DataTable m_dataTable = null;
2/**//// <summary>
3 /// Gets the data table form.
4 /// </summary>
5 /// <value>The data table form.</value>
6 public DataTable DataTableForm
7 {
8 get { return m_dataTable; }
9 }
10
因为前面有提到了,一个对象对应一个DataRow,当前一个对象单独存在时,它的数据存放在数据类的 数据容器里,而当中被加到一个集合里时,数据行就应该存放在数据集合对应的DataTable里了。那要怎 么转换呢?很简单,只需要把数据行从原来(数据类的数据容器)的表里面复制到ObjectList对应的 DataTable里,然后将原来的行删除就行了。这里复制一行数据也是有学问的,因为一个DataRow一旦创建 了,它就只能被加入到创建它的那个DataTable里,当它被加入到另外一个表里就会抛出它同时只能属于 一个表的异常,而如果是DataRow里的数据一列一列地复制到另一个DataRow,就会对性能造成非常大的影 响。最理想的办法就是数据不动,只改变DataRow记录的一个状态信息就行了。这里的改变行状态的办法 就是NewRow,而数据不动的办法就是将源Row的ItemArray属性赋值给目的的ItemArray。经过测试,这样 做可以减少1倍以上的时间成本(内存成本也一样)。
具体的添加方法如下:
1private void AddObjectRowToListTable(IDataObject p_dataObject)
2 {
3 if (m_dataTable == null)
4 m_dataTable = p_dataObject.DataContainer.Clone();
5 DataRow m_newRow = m_dataTable.NewRow();
6 m_newRow.ItemArray = p_dataObject.ObjectRow.ItemArray;
7 /**//***********************************************
8 * 使用上面代 码时间性能会比下面的高一倍
9 * for (int i = 0; i < p_dataObject.ObjectRow.ItemArray.Length; i++)
10 {
11 m_newRow[i] = p_dataObject.ObjectRow.ItemArray[i];
12 }
13 * ********************************************/
14
15 m_dataTable.Rows.Add(m_newRow);
16 p_dataObject.ObjectRow.Delete ();
17 p_dataObject.ObjectRow.Table.AcceptChanges();
18 p_dataObject.ObjectRow = m_newRow;
19 }
20