继上一节,回头看这张图片:
回顾上节的话题,怎么设计这样一个数据单元类?才不会有重复的单元表头,又能合理解释出数据与表头的关系?
经过长久的深思后。。一个关键的字出来了"ref",引用,是的,用的这就个,如果每个单元格,都包括值和单元表头,而单元表头,都引用同一个的时候,就刚好满足了需求。
于是,我们开始写出这样的类:
先构造出一个存放值的类:
///
<summary>
/// 只包函被填充的数据状态和值
/// </summary>
public class MDataCellValue
{
/// <summary>
/// //值是否为空
/// </summary>
internal bool _IsNull;
/// <summary>
/// 值是否被改变了
/// </summary>
internal bool _IsChange;
/// <summary>
/// 值是多少
/// </summary>
internal object _Value;
public MDataCellValue()
{
_IsNull = true ;
_IsChange = false ;
_Value = null ;
}
}
/// 只包函被填充的数据状态和值
/// </summary>
public class MDataCellValue
{
/// <summary>
/// //值是否为空
/// </summary>
internal bool _IsNull;
/// <summary>
/// 值是否被改变了
/// </summary>
internal bool _IsChange;
/// <summary>
/// 值是多少
/// </summary>
internal object _Value;
public MDataCellValue()
{
_IsNull = true ;
_IsChange = false ;
_Value = null ;
}
}
接着,我们构造存放表头:
我们可以参考数据库,也可以参考DataCell中的数据结构,构造出以下的类:
///
<summary>
/// 只包函数据库字段的属性
/// </summary>
public class MDataCellStruct
{
internal bool _IsCanNull;
internal bool _IsReadOnly;
internal string _ColumnName;
internal System.Data.SqlDbType _SqlType;
internal int _MaxSize;
internal string _Operator = " = " ;
internal ParameterDirection _ParaDirection;
#region 构造函数
public MDataCellStruct( string ColumnName, System.Data.SqlDbType SqlType, bool IsReadOnly, bool IsCanNull, int MaxSize, ParameterDirection paraDirection)
{
_ColumnName = ColumnName;
_SqlType = SqlType;
_IsReadOnly = IsReadOnly;
_IsCanNull = IsCanNull;
_MaxSize = MaxSize;
_ParaDirection = paraDirection;
}
#endregion
#region 属性
/// <summary>
/// 数据字段列名称
/// </summary>
public string ColumnName
{
get
{
return this ._ColumnName;
}
}
/// <summary>
/// 数据类型
/// </summary>
public System.Data.SqlDbType SqlType
{
get
{
return this ._SqlType;
}
}
/// <summary>
/// 数据字段列是否为只读
/// </summary>
public bool IsReadOnly
{
get
{
return this ._IsReadOnly;
}
}
/// <summary>
/// 数据字段列长度大小
/// </summary>
public int MaxSize
{
get
{
return this ._MaxSize;
}
}
/// <summary>
/// 数据字段列值是否能为空
/// </summary>
public bool IsCanNull
{
get
{
return this ._IsCanNull;
}
}
/// <summary>
/// 存储过程时用的参数
/// </summary>
public ParameterDirection ParaDirection
{
get
{
return this ._ParaDirection;
}
set
{
_ParaDirection = (ParameterDirection)value;
}
}
public string Operator
{
get
{
return _Operator;
}
set
{
_Operator = value;
}
}
#endregion
}
/// 只包函数据库字段的属性
/// </summary>
public class MDataCellStruct
{
internal bool _IsCanNull;
internal bool _IsReadOnly;
internal string _ColumnName;
internal System.Data.SqlDbType _SqlType;
internal int _MaxSize;
internal string _Operator = " = " ;
internal ParameterDirection _ParaDirection;
#region 构造函数
public MDataCellStruct( string ColumnName, System.Data.SqlDbType SqlType, bool IsReadOnly, bool IsCanNull, int MaxSize, ParameterDirection paraDirection)
{
_ColumnName = ColumnName;
_SqlType = SqlType;
_IsReadOnly = IsReadOnly;
_IsCanNull = IsCanNull;
_MaxSize = MaxSize;
_ParaDirection = paraDirection;
}
#endregion
#region 属性
/// <summary>
/// 数据字段列名称
/// </summary>
public string ColumnName
{
get
{
return this ._ColumnName;
}
}
/// <summary>
/// 数据类型
/// </summary>
public System.Data.SqlDbType SqlType
{
get
{
return this ._SqlType;
}
}
/// <summary>
/// 数据字段列是否为只读
/// </summary>
public bool IsReadOnly
{
get
{
return this ._IsReadOnly;
}
}
/// <summary>
/// 数据字段列长度大小
/// </summary>
public int MaxSize
{
get
{
return this ._MaxSize;
}
}
/// <summary>
/// 数据字段列值是否能为空
/// </summary>
public bool IsCanNull
{
get
{
return this ._IsCanNull;
}
}
/// <summary>
/// 存储过程时用的参数
/// </summary>
public ParameterDirection ParaDirection
{
get
{
return this ._ParaDirection;
}
set
{
_ParaDirection = (ParameterDirection)value;
}
}
public string Operator
{
get
{
return _Operator;
}
set
{
_Operator = value;
}
}
#endregion
}
紧跟着,我们要开始构造单元格了,它包含了数据单元结构和值两个类,同时,为了让以后所有行的单元格里的表头都指向同一个,我们用出了"ref"
public class MDataCell
{
internal MDataCellValue _ValueContainer;
private MDataCellStruct _DataStruct;
构造函数
初始化
}
为了方便从数据单元里访问数据结构和值,我们通过增加属性来对外开放
#region 属性
字段结构
/// <summary>
/// 字段结构
/// </summary>
public MDataCellStruct DataStruct
{
get
{
return _DataStruct;
}
}
/// <summary>
/// 数据字段列值是否能改变
/// </summary>
public bool IsChange
{
get
{
return _ValueContainer._IsChange;
}
set
{
_ValueContainer._IsChange = value;
}
}
/// <summary>
/// 数据字段列值是否为空
/// </summary>
public bool IsNull
{
get
{
return _ValueContainer._IsNull;
}
}
/// <summary>
/// 数据字段列值
/// </summary>
public object Value
{
get
{
return _ValueContainer._Value;
}
set
{
if (_DataStruct._IsCanNull)//数据库允许为null值
{
_ValueContainer._Value = value;
_ValueContainer._IsChange = true;
_ValueContainer._IsNull = (value == null || value == DBNull.Value);
}
else if (value != null && value != DBNull.Value)//数据库不允许为null值不允许为null值
{
_ValueContainer._Value = value;
_ValueContainer._IsChange = true;
_ValueContainer._IsNull = false;
}
}
}
#endregion
至此,我们终于构造完数据单元格,当然了,在对Value的Set属性中,以后我们会加上数据类型的比较和数据长度的验证,来增加数据的安全性