当前架构中的get方法
一、 编写目的
当前架构中,通过get方法取得数据库中的一条记录。当前这种方法有几个问题:
1. 如何处理空数据的问题,例如某条记录的第x列的记录为空时,如何写入到相关DT类的相关字段(属性)中。
2. 2: 需要对每一个数据库设置一个从DataRow或IdataReader向DT类中写入数据的代码。
以上这两点,对日常开发带来一定的疑惑。本文试图对上面两个问题,提出一个解决方案。
二、 代码分析
以下是对get方法代码及其相关代码的分析。
(一) 当前实现代码
DB类中Get方法:
/// <summary>
/// 获取一条纪录
/// </summary>
public AwakedetailDT Get(int sysCode) {
AwakedetailDT detail= new AwakedetailDT();
try {
string sql= "select * from awakeDetail where (sysCode="+ sysCode+")";
DataTable dt= this.ExecuteForDataTable(sql);
DataRow dr=null;
int rowCount= dt.Rows.Count;
if (rowCount>0) {
dr= dt.Rows[0];
detail.sysCode= Convert.ToInt32(dr["sysCode"]);
detail.personID= Convert.ToInt32(dr["personID"]);
detail.pkID= Convert.ToInt32(dr["pkID"]);
detail.awakeTitle= Convert.ToString(dr["awakeTitle"]);
detail.aimURL= Convert.ToString(dr["aimURL"]);
detail.columnName= Convert.ToString(dr["columnName"]);
detail.awakeType= Convert.ToInt32(dr["awakeType"]);
detail.awakeMode= Convert.ToInt32(dr["awakeMode"]);
detail.circle= Convert.ToInt32(dr["circle"]);
detail.circleType= Convert.ToInt32(dr["circleType"]);
detail.awakeTime= Convert.ToDecimal(dr["awakeTime"]);
detail.advDays= Convert.ToInt32(dr["advDays"]);
detail.lastTime= Convert.ToDecimal(dr["lastTime"]);
detail.finished= Convert.ToInt32(dr["finished"]);
}
}
catch(Exception ex) {
throw ex;
}
finally {
}
return detail;
}
在上面的代码中,存在如下几个问题:
1:如果dt.Rows[0]中的列“awakeTime”为空的时候,编译本段代码就会出现问题。
2:每个DB中,要重新写一遍代码:
int rowCount= dt.Rows.Count;
if (rowCount>0) {
dr= dt.Rows[0];
….
可重用性差。
(二) 一个解决方案
以下是解决上述问题的一个解决方案:
首先,取得一条数据库表的记录到DataTable或IdataReader中。然后调用类CBO来生成需要的对象。在生成对象的时候,会判断DataTable或IdataReader中的数据是否为空,如果为空,以类Null中的值填充该数据。
DB类中的get方法:取得数据库中的记录,并生成相关对象:
/// <summary>
/// Description:取得一条记录。
/// </summary>
/// <param name="detail">一条记录</param>
/// <returns>一条记录</returns>
/// <author></author>
/// <log date="
public object Get(object detail)
{
string sql= "select * from awakeDetail where (sysCode="+ sysCode+")";
IdataReader dt= this.ExecuteForDataTable(sql);
//调用CBO中的FillConllection方法生成AwakedetailDT对象
return CBO.FillObject(read, detail.GetType(), true);
}
CBO:生成需要的对象。
using System;
using System.Data;
using System.Web.Caching;
using System.Reflection;
using System.Xml;
using System.Xml.Serialization;
using System.Text;
using System.IO;
using System.Collections;
using Microsoft.VisualBasic;
namespace DOCNET.Utils
{
/// <summary>
/// CBO 的摘要说明。
/// </summary>
public class CBO
{
public CBO()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
/// <summary>
/// 返回存储某类型[objType]的所有属性(property)的集合。
/// </summary>
/// <param name="objType">类型(类、接口、枚举等)</param>
/// <returns>属性集合</returns>
public static ArrayList GetPropertyInfo(Type objType)
{
ArrayList objProperties = null;
// 如果属性集合为空
if (objProperties == null)
{
// 初始化集合
objProperties = new ArrayList();
// PropertyInfo:发现属性的特性并提供对属性元数据的访问。
// GetProperties:返回当前Type的所有公共属性。
foreach (PropertyInfo objProperty in objType.GetProperties())
{
// 用属性填充集合
objProperties.Add(objProperty);
}
}
// 返回类型集合
return objProperties;
}
/// <summary>
/// 返回dr属性字段索引的数组。
/// </summary>
/// <param name="objProperties">属性数组[存储着dr的列字段名称的属性]</param>
/// <param name="dr"></param>
/// <returns>字段索引的数组</returns>
public static int[] GetOrdinals(ArrayList objProperties, IDataReader dr)
{
// 形成对应属性集合的整合数组
int[] arrOrdinals = new int[objProperties.Count];
int count;
if (dr != null)
{
count = objProperties.Count;
for (int intProperty = 0; intProperty < count; intProperty++)
{
arrOrdinals[intProperty] = -1;
try
{
PropertyInfo propertyInfo = (PropertyInfo)objProperties[intProperty];
// GetOrdinal:返回命名字段的索引。
// propertyInfo.Name:获取此成员的名称。
// 该行试图返回字段名称为propertyInfo.Name的DataReader的列索引
arrOrdinals[intProperty] = dr.GetOrdinal(propertyInfo.Name);
}
catch
{
}
}
}
// 返回命名字段索引的数组
return arrOrdinals;
}
/// <summary>
/// 给objType类型的对象逐个赋属性值并返回该对象。
/// </summary>
/// <param name="objType">对象类型</param>
/// <param name="dr">存储记录的DataReader</param>
/// <param name="objProperties">属性集合</param>
/// <param name="arrOrdinals">索引集合</param>
/// <returns>objType类型对象</returns>
private static object CreateObject(Type objType, IDataReader dr, ArrayList objProperties, int[] arrOrdinals)
{
// 在这儿声明对象,估计是为了性能考虑
PropertyInfo objPropertyInfo;
object objValue;
Type objPropertyType = null;
// 创建objType类型的对象
object objObject = Activator.CreateInstance(objType);
int objPropertiesCount = objProperties.Count;
for (int intProperty = 0; intProperty < objPropertiesCount; intProperty++)
{
// 取得第intProperty个属性
objPropertyInfo = (PropertyInfo)objProperties[intProperty];
// 如果该属性允许写入/含有Set的属性
if (objPropertyInfo.CanWrite)
{
// 将objValue设置为空 根据objPropertyInfo.PropertyType值
objValue = Null.SetNull(objPropertyInfo);
// 如果索引不存在
if (arrOrdinals[intProperty] == -1)
{
continue;
}
// 判断dr的第arrOrdinals[intProperty]格元素是空
if (Information.IsDBNull(dr.GetValue(arrOrdinals[intProperty])))
{
// 将给定对象的属性值设置为给定值[即相应的空值]
objPropertyInfo.SetValue(objObject, objValue, null);
continue;
}
// 如果无错误,赋值,设置下一个属性
try
{
// 将给定对象的属性值设置为给定值
objPropertyInfo.SetValue(objObject, dr.GetValue(arrOrdinals[intProperty]), null);
continue;
}
catch
{
}
// 如果设置不成功
try
{
// 取得相应数据类型
objPropertyType = objPropertyInfo.PropertyType;
// BaseType:获取当前 System.Type 直接从中继承的类型
// 如果类型不是枚举
if (!objPropertyType.BaseType.Equals(typeof(System.Enum)))
{
objPropertyInfo.SetValue(objObject, Convert.ChangeType(dr.GetValue(arrOrdinals[intProperty]), objPropertyType), null);
continue;
}
// BaseType:获取当前 System.Type 直接从中继承的类型
// 如果类型是枚举
// 判断dr的第arrOrdinals[intProperty]格元素是不是数字
if (Information.IsNumeric(dr.GetValue(arrOrdinals[intProperty])))
{
// 将给定对象的属性值设置为给定值 即第Convert.ToInt32(dr.GetValue(arrOrdinals[intProperty])个枚举值
((PropertyInfo)objProperties[intProperty]).SetValue(objObject, System.Enum.ToObject(objPropertyType, Convert.ToInt32(dr.GetValue(arrOrdinals[intProperty]))), null);
}
else
{
// 将给定对象的属性值设置为给定值
((PropertyInfo)objProperties[intProperty]).SetValue(objObject, System.Enum.ToObject(objPropertyType,dr.GetValue(arrOrdinals[intProperty])), null);
}
}
catch
{
// 将给定对象的属性值设置为给定值
objPropertyInfo.SetValue(objObject, Convert.ChangeType(dr.GetValue(arrOrdinals[intProperty]), objPropertyType), null);
}
}
}
// 返回objObject对象
return objObject;
}
/// <summary>
/// 用dr填充一个objType对象,并返回。
/// </summary>
/// <param name="dr">存储对象数据的DataReader</param>
/// <param name="objType">对象类型</param>
/// <returns>objType对象</returns>
public static object FillObject(IDataReader dr, Type objType)
{
return FillObject(dr, objType, true);
}
/// <summary>
/// 用dr填充一个objType对象,并返回。
/// </summary>
/// <param name="dr">存储对象数据的DataReader</param>
/// <param name="objType">对象类型</param>
/// <param name="ManageDataReader"></param>
/// <returns>objType对象</returns>
public static object FillObject(IDataReader dr, Type objType, bool ManageDataReader)
{
object objFillObject;
// GetPropertyInfo:返回存储某类型的所有属性的集合。
// 取得属性集合
ArrayList objProperties = GetPropertyInfo(objType);
// GetOrdinals:返回dr属性字段索引的数组。
// 返回索引数组
int[] arrOrdinals = GetOrdinals(objProperties, dr);
bool Continue = true;
// 要不要继续,如果dr不到最后,继续
if (ManageDataReader)
{
Continue = false;
if (dr.Read())
{
Continue = true;
}
}
if (Continue)
{
// CreateObject:给objType类型的对象逐个赋值并返回。
objFillObject = CreateObject(objType, dr, objProperties, arrOrdinals);
}
else
{
objFillObject = null;
}
if (ManageDataReader)
{
if (dr != null)
{
dr.Close();
}
}
// 返回对象
return objFillObject;
}
/// <summary>
/// 用dr填充一个objType对象数组,并返回。
/// </summary>
/// <param name="dr">存储对象数据的DataReader</param>
/// <param name="objType">对象类型</param>
/// <returns>对象数组</returns>
public static ArrayList FillConllection(IDataReader dr, Type objType)
{
// 一个集合
ArrayList objFillCollection = new ArrayList();
object objFillObject;
// GetPropertyInfo:返回存储某类型的所有属性的集合。
// 取得objType类/接口的属性集合
ArrayList objProperties = GetPropertyInfo(objType);
// GetOrdinals:返回dr属性字段索引的数组。
// 返回索引数组
int[] arrOrdinals = GetOrdinals(objProperties, dr);
// 生成多个objType对象
while(dr.Read())
{
objFillObject = CreateObject(objType, dr, objProperties, arrOrdinals);
objFillCollection.Add(objFillObject);
}
if (dr != null)
{
dr.Close();
}
// 返回对象数组
return objFillCollection;
}
/// <summary>
/// 用dr填充一个IList,并返回。
/// </summary>
/// <param name="dr">存储对象数据的DataReader</param>
/// <param name="objType">对象类型</param>
/// <param name="objToFill">IList</param>
/// <returns>IList</returns>
public static IList FillCollection(IDataReader dr, Type objType, IList objToFill)
{
object objFillObject;
// GetPropertyInfo:返回存储某类型的所有属性的集合。
// 取得objType类/接口的属性集合
ArrayList objProperties = GetPropertyInfo(objType);
// GetOrdinals:返回dr属性字段索引的数组。
// 返回索引数组
int[] arrOrdinals = GetOrdinals(objProperties, dr);
// 生成多个objType对象
while (dr.Read())
{
objFillObject = CreateObject(objType, dr, objProperties, arrOrdinals);
objToFill.Add(objFillObject);
}
if (dr != null)
{
dr.Close();
}
// 返回IList
return objToFill;
}
/// <summary>
/// 给objType类型的对象赋初始值[空值]。
/// </summary>
/// <param name="objObject">赋值对象</param>
/// <param name="objType">对象类型</param>
/// <returns>赋初始值的对象</returns>
public static object InitializeObject(object objObject, Type objType)
{
PropertyInfo objPropertyInfo;
object objValue;
// GetPropertyInfo:返回存储某类型的所有属性的集合。
// 取得objType类/接口的属性集合
ArrayList objProperties = GetPropertyInfo(objType);
// 依次赋值
for (int intProperty = 0; intProperty < objProperties.Count; intProperty++)
{
// 取得第intProperty个属性
objPropertyInfo = (PropertyInfo)objProperties[intProperty];
// 如果该属性允许写入
if (objPropertyInfo.CanWrite)
{
// 将objValue设置为空 根据objPropertyInfo.PropertyType值
objValue = Null.SetNull(objPropertyInfo);
// 将给定对象的属性值设置为给定值
objPropertyInfo.SetValue(objObject, objValue, null);
}
}
// 返回对象
return objObject;
}
/// <summary>
/// 根据字段名成取得字段列的索引号。
/// </summary>
/// <param name="name"></param>
/// <param name="dcl"></param>
/// <returns></returns>
public static int GetIndexForDataTable(string name, DataColumnCollection dcl)
{
int count = dcl.Count;
for (int i = 0; i < count; i++)
{
if (string.Compare(dcl[i].ColumnName, name, true) == 0)
{
return i;
}
}
return -1;
}
// <summary>
/// 返回dr属性字段索引的数组。
/// </summary>
/// <param name="objProperties">属性数组[存储着dr的列字段名称的属性]</param>
/// <param name="dr"></param>
/// <returns>字段索引的数组</returns>
public static int[] GetOrdinals(ArrayList objProperties, DataRow dr)
{
// 形成对应属性集合的整合数组
int[] arrOrdinals = new int[objProperties.Count];
int count;
if (dr != null)
{
DataColumnCollection dcl = dr.Table.Columns;
count = objProperties.Count;
for (int i = 0; i < count; i++)
{
arrOrdinals[i] = -1;
try
{
PropertyInfo propertyInfo = (PropertyInfo)objProperties[i];
// GetOrdinal:返回命名字段的索引。
// propertyInfo.Name:获取此成员的名称。
// 该行试图返回字段名称为propertyInfo.Name的DataReader的列索引
arrOrdinals[i] = GetIndexForDataTable(propertyInfo.Name, dcl);
}
catch
{
}
}
}
// 返回命名字段索引的数组
return arrOrdinals;
}
/// <summary>
/// 给objType类型的对象逐个赋属性值并返回该对象。
/// </summary>
/// <param name="objType">对象类型</param>
/// <param name="dr">存储记录的DataRow</param>
/// <param name="objProperties">属性集合</param>
/// <param name="arrOrdinals">索引集合</param>
/// <returns>objType类型对象</returns>
private static object CreateObject(Type objType, DataRow dr, ArrayList objProperties, int[] arrOrdinals)
{
// 在这儿声明对象,估计是为了性能考虑
PropertyInfo objPropertyInfo;
object objValue;
Type objPropertyType = null;
// 创建objType类型的对象
object objObject = Activator.CreateInstance(objType);
int objPropertiesCount = objProperties.Count;
for (int intProperty = 0; intProperty < objPropertiesCount; intProperty++)
{
// 取得第intProperty个属性
objPropertyInfo = (PropertyInfo)objProperties[intProperty];
// 如果该属性允许写入/含有Set的属性
if (objPropertyInfo.CanWrite)
{
// 将objValue设置为空 根据objPropertyInfo.PropertyType值
objValue = Null.SetNull(objPropertyInfo);
// 如果索引不存在
if (arrOrdinals[intProperty] == -1)
{
continue;
}
// 判断dr的第arrOrdinals[intProperty]格元素是空
if (Information.IsDBNull(dr[arrOrdinals[intProperty]]))
{
// 将给定对象的属性值设置为给定值[即相应的空值]
objPropertyInfo.SetValue(objObject, objValue, null);
continue;
}
// 如果无错误,赋值,设置下一个属性
try
{
// 将给定对象的属性值设置为给定值
objPropertyInfo.SetValue(objObject, dr[arrOrdinals[intProperty]], null);
continue;
}
catch
{
}
// 如果设置不成功
try
{
// 取得相应数据类型
objPropertyType = objPropertyInfo.PropertyType;
// BaseType:获取当前 System.Type 直接从中继承的类型
// 如果类型不是枚举
if (!objPropertyType.BaseType.Equals(typeof(System.Enum)))
{
objPropertyInfo.SetValue(objObject, Convert.ChangeType(dr[arrOrdinals[intProperty]], objPropertyType), null);
continue;
}
// BaseType:获取当前 System.Type 直接从中继承的类型
// 如果类型是枚举
// 判断dr的第arrOrdinals[intProperty]格元素是不是数字
if (Information.IsNumeric(dr[arrOrdinals[intProperty]]))
{
// 将给定对象的属性值设置为给定值 即第Convert.ToInt32(dr[arrOrdinals[intProperty]]个枚举值
((PropertyInfo)objProperties[intProperty]).SetValue(objObject, System.Enum.ToObject(objPropertyType, Convert.ToInt32(dr[arrOrdinals[intProperty]])), null);
}
else
{
// 将给定对象的属性值设置为给定值
((PropertyInfo)objProperties[intProperty]).SetValue(objObject, System.Enum.ToObject(objPropertyType,dr[arrOrdinals[intProperty]]), null);
}
}
catch
{
// 将给定对象的属性值设置为给定值
objPropertyInfo.SetValue(objObject, Convert.ChangeType(dr[arrOrdinals[intProperty]], objPropertyType), null);
}
}
}
// 返回objObject对象
return objObject;
}
/// <summary>
/// 用dr填充一个objType对象,并返回。
/// </summary>
/// <param name="dr">存储对象数据的DataRow</param>
/// <param name="objType">对象类型</param>
/// <returns>objType对象</returns>
public static object FillObject(DataRow dr, Type objType)
{
return FillObject(dr, objType, true);
}
/// <summary>
/// 用dr填充一个objType对象,并返回。
/// </summary>
/// <param name="dr">存储对象数据的DataRow</param>
/// <param name="objType">对象类型</param>
/// <param name="ManageDataReader"></param>
/// <returns>objType对象</returns>
public static object FillObject(DataRow dr, Type objType, bool ManageDataReader)
{
object objFillObject;
// GetPropertyInfo:返回存储某类型的所有属性的集合。
// 取得属性集合
ArrayList objProperties = GetPropertyInfo(objType);
// GetOrdinals:返回dr属性字段索引的数组。
// 返回索引数组
int[] arrOrdinals = GetOrdinals(objProperties, dr);
bool Continue = true;
if (Continue)
{
// CreateObject:给objType类型的对象逐个赋值并返回。
objFillObject = CreateObject(objType, dr, objProperties, arrOrdinals);
}
else
{
objFillObject = null;
}
// 返回对象
return objFillObject;
}
/// <summary>
/// 返回存储某类型[objType]的所有字段(property)的集合。
/// </summary>
/// <param name="objType">类型(类、接口、枚举等)</param>
/// <returns>属性集合</returns>
public static ArrayList GetFieldInfo(Type objType)
{
ArrayList objFields = null;
// 如果属性集合为空
if (objFields == null)
{
// 初始化集合
objFields = new ArrayList();
// PropertyInfo:发现属性的特性并提供对属性元数据的访问。
// GetProperties:返回当前Type的所有公共属性。
foreach (FieldInfo objField in objType.GetFields())
{
// 用属性填充集合
objFields.Add(objField);
}
}
// 返回类型集合
return objFields;
}
/// <summary>
/// 返回dr字段索引的数组。
/// </summary>
/// <param name="objfields">属性数组[存储着dr的列字段名称的属性]</param>
/// <param name="dr"></param>
/// <returns>字段索引的数组</returns>
public static int[] GetOrdinalsForField(ArrayList objfields, IDataReader dr)
{
// 形成对应属性集合的整合数组
int[] arrOrdinals = new int[objfields.Count];
int count;
if (dr != null)
{
count = objfields.Count;
for (int i = 0; i < count; i++)
{
arrOrdinals[i] = -1;
try
{
FieldInfo fieldInfo = ( FieldInfo)objfields[i];
// GetOrdinal:返回命名字段的索引。
// propertyInfo.Name:获取此成员的名称。
// 该行试图返回字段名称为propertyInfo.Name的DataReader的列索引
arrOrdinals[i] = dr.GetOrdinal(fieldInfo.Name);
}
catch
{
}
}
}
// 返回命名字段索引的数组
return arrOrdinals;
}
/// <summary>
/// 给objType类型的对象逐个赋属性值并返回该对象。
/// </summary>
/// <param name="objType">对象类型</param>
/// <param name="dr">存储记录的DataReader</param>
/// <param name="objProperties">属性集合</param>
/// <param name="arrOrdinals">索引集合</param>
/// <returns>objType类型对象</returns>
private static object CreateObjectByField(Type objType, IDataReader dr, ArrayList objFields, int[] arrOrdinals)
{
// 在这儿声明对象,估计是为了性能考虑
FieldInfo objFieldInfo;
object objValue;
Type objFieldType = null;
// 创建objType类型的对象
object objObject = Activator.CreateInstance(objType);
int objFieldsCount = objFields.Count;
for (int intProperty = 0; intProperty < objFieldsCount; intProperty++)
{
// 取得第intProperty个属性
objFieldInfo = (FieldInfo)objFields[intProperty];
// 如果该属性允许写入/含有Set的属性
if (objFieldInfo.IsPublic && (!objFieldInfo.IsInitOnly))
{
// 将objValue设置为空 根据objPropertyInfo.PropertyType值
objValue = Null.SetNull(objFieldInfo);
// 如果索引不存在
if (arrOrdinals[intProperty] == -1)
{
continue;
}
// 判断dr的第arrOrdinals[intProperty]格元素是空
if (Information.IsDBNull(dr.GetValue(arrOrdinals[intProperty])))
{
// 将给定对象的属性值设置为给定值[即相应的空值]
objFieldInfo.SetValue(objObject, objValue);
continue;
}
// 如果无错误,赋值,设置下一个属性
try
{
// 将给定对象的属性值设置为给定值
objFieldInfo.SetValue(objObject, dr.GetValue(arrOrdinals[intProperty]));
continue;
}
catch
{
}
// 如果设置不成功
try
{
// 取得相应数据类型
objFieldType = objFieldInfo.FieldType;
// BaseType:获取当前 System.Type 直接从中继承的类型
// 如果类型不是枚举
if (!objFieldType.BaseType.Equals(typeof(System.Enum)))
{
objFieldInfo.SetValue(objObject, Convert.ChangeType(dr.GetValue(arrOrdinals[intProperty]), objFieldType));
continue;
}
// BaseType:获取当前 System.Type 直接从中继承的类型
// 如果类型是枚举
// 判断dr的第arrOrdinals[intProperty]格元素是不是数字
if (Information.IsNumeric(dr.GetValue(arrOrdinals[intProperty])))
{
// 将给定对象的属性值设置为给定值 即第Convert.ToInt32(dr.GetValue(arrOrdinals[intProperty])个枚举值
((FieldInfo)objFields[intProperty]).SetValue(objObject, System.Enum.ToObject(objFieldType, Convert.ToInt32(dr.GetValue(arrOrdinals[intProperty]))));
}
else
{
// 将给定对象的属性值设置为给定值
((FieldInfo)objFields[intProperty]).SetValue(objObject, System.Enum.ToObject(objFieldType,dr.GetValue(arrOrdinals[intProperty])));
}
}
catch
{
// 将给定对象的属性值设置为给定值
objFieldInfo.SetValue(objObject, Convert.ChangeType(dr.GetValue(arrOrdinals[intProperty]), objFieldType));
}
}
}
// 返回objObject对象
return objObject;
}
/// <summary>
/// 用dr填充一个objType对象,并返回。
/// </summary>
/// <param name="dr">存储对象数据的DataReader</param>
/// <param name="objType">对象类型</param>
/// <returns>objType对象</returns>
public static object FillObjectByField(IDataReader dr, Type objType)
{
return FillObjectByField(dr, objType, true);
}
/// <summary>
/// 用dr填充一个objType对象,并返回。
/// </summary>
/// <param name="dr">存储对象数据的DataReader</param>
/// <param name="objType">对象类型</param>
/// <param name="ManageDataReader"></param>
/// <returns>objType对象</returns>
public static object FillObjectByField(IDataReader dr, Type objType, bool ManageDataReader)
{
object objFillObject;
// GetPropertyInfo:返回存储某类型的所有属性的集合。
// 取得属性集合
ArrayList objFields = GetFieldInfo(objType);
// GetOrdinals:返回dr属性字段索引的数组。
// 返回索引数组
int[] arrOrdinals = GetOrdinalsForField(objFields, dr);
bool Continue = true;
// 要不要继续,如果dr不到最后,继续
if (ManageDataReader)
{
Continue = false;
if (dr.Read())
{
Continue = true;
}
}
if (Continue)
{
// CreateObject:给objType类型的对象逐个赋值并返回。
objFillObject = CreateObjectByField(objType, dr, objFields, arrOrdinals);
}
else
{
objFillObject = null;
}
if (ManageDataReader)
{
if (dr != null)
{
dr.Close();
}
}
// 返回对象
return objFillObject;
}
/// <summary>
/// 用dr填充一个objType对象数组,并返回。
/// </summary>
/// <param name="dr">存储对象数据的DataReader</param>
/// <param name="objType">对象类型</param>
/// <returns>对象数组</returns>
public static ArrayList FillConllectionByField(IDataReader dr, Type objType)
{
// 一个集合
ArrayList objFillCollection = new ArrayList();
object objFillObject;
// GetPropertyInfo:返回存储某类型的所有属性的集合。
// 取得objType类/接口的属性集合
ArrayList objFields = GetFieldInfo(objType);
// GetOrdinals:返回dr属性字段索引的数组。
// 返回索引数组
int[] arrOrdinals = GetOrdinalsForField(objFields, dr);
// 生成多个objType对象
while(dr.Read())
{
objFillObject = CreateObjectByField(objType, dr, objFields, arrOrdinals);
objFillCollection.Add(objFillObject);
}
if (dr != null)
{
dr.Close();
}
// 返回对象数组
return objFillCollection;
}
/// <summary>
/// 用dr填充一个IList,并返回。
/// </summary>
/// <param name="dr">存储对象数据的DataReader</param>
/// <param name="objType">对象类型</param>
/// <param name="objToFill">IList</param>
/// <returns>IList</returns>
public static IList FillCollectionByField(IDataReader dr, Type objType, IList objToFill)
{
object objFillObject;
// GetPropertyInfo:返回存储某类型的所有属性的集合。
// 取得objType类/接口的属性集合
ArrayList objFields = GetFieldInfo(objType);
// GetOrdinals:返回dr属性字段索引的数组。
// 返回索引数组
int[] arrOrdinals = GetOrdinalsForField(objFields, dr);
// 生成多个objType对象
while (dr.Read())
{
objFillObject = CreateObjectByField(objType, dr, objFields, arrOrdinals);
objToFill.Add(objFillObject);
}
if (dr != null)
{
dr.Close();
}
// 返回IList
return objToFill;
}
}
}
Null:存储某类型数据为空时的值。
using System;
using System.Reflection;
namespace DOCNET.Utils
{
/// <summary>
/// Null 的摘要说明。
/// </summary>
public class Null
{
public Null()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
public static short NullShort
{
get
{
return -1;
}
}
public static int NullInteger
{
get
{
return -1;
}
}
public static Single NullSingle
{
get
{
return Single.MinValue;
}
}
public static double NullDouble
{
get
{
return double.MinValue;
}
}
public static decimal NullDecimal
{
get
{
return decimal.MinValue;
}
}
public static DateTime NullDate
{
get
{
return DateTime.MinValue;
}
}
public static string NullString
{
get
{
return "";
}
}
public static bool NullBoolean
{
get
{
return false;
}
}
public static Guid NullGuid
{
get
{
return Guid.Empty;
}
}
public static object SetNull(object objValue, object objField)
{
object ret;
if (objValue is DBNull)
{
if (objField is short)
{
ret = NullShort;
}
else if (objField is int)
{
ret = NullInteger;
}
else if (objField is Single)
{
ret = NullSingle;
}
else if (objField is double)
{
ret = NullDouble;
}
else if (objField is decimal)
{
ret = NullDecimal;
}
else if (objField is DateTime)
{
ret = NullDate;
}
else if (objField is string)
{
ret = NullString;
}
else if (objField is bool)
{
ret = NullBoolean;
}
else if (objField is Guid)
{
ret = NullGuid;
}
else
{
ret = null;
}
}
else
{
ret = objValue;
}
return ret;
}
public static object SetNull(PropertyInfo objPropertyInfo)
{
object ret;
switch (objPropertyInfo.PropertyType.ToString())
{
case "System.Int16":
ret = NullShort;
break;
case "System.Int32":
case "System.Int64":
ret = NullInteger;
break;
case "System.Single":
ret = NullSingle;
break;
case "System.Double":
ret = NullDouble;
break;
case "System.Decimal":
ret = NullDecimal;
break;
case "System.DateTime":
ret = NullDate;
break;
case "System.String":
case "System.Char":
ret = NullString;
break;
case "System.Boolean":
ret = NullBoolean;
break;
case "System.Guid":
ret = NullGuid;
break;
default:
Type pType = objPropertyInfo.PropertyType;
if (pType.BaseType.Equals(typeof(System.Enum)))
{
Array objEnumValues = Enum.GetValues(pType);
Array.Sort(objEnumValues);
ret = Enum.ToObject(pType, objEnumValues.GetValue(0));
}
else
{
ret = null;
}
break;
}
return ret;
}
public static object SetNull(FieldInfo objFieldInfo)
{
object ret;
switch (objFieldInfo.FieldType.ToString())
{
case "System.Int16":
ret = NullShort;
break;
case "System.Int32":
case "System.Int64":
ret = NullInteger;
break;
case "System.Single":
ret = NullSingle;
break;
case "System.Double":
ret = NullDouble;
break;
case "System.Decimal":
ret = NullDecimal;
break;
case "System.DateTime":
ret = NullDate;
break;
case "System.String":
case "System.Char":
ret = NullString;
break;
case "System.Boolean":
ret = NullBoolean;
break;
case "System.Guid":
ret = NullGuid;
break;
default:
Type pType = objFieldInfo.FieldType;
if (pType.BaseType.Equals(typeof(System.Enum)))
{
Array objEnumValues = Enum.GetValues(pType);
Array.Sort(objEnumValues);
ret = Enum.ToObject(pType, objEnumValues.GetValue(0));
}
else
{
ret = null;
}
break;
}
return ret;
}
public static object GetNull(object objField, object objDBNull)
{
object ret = objField;
if (objField == null)
{
ret = objDBNull;
}
else if (objField is short)
{
if (Convert.ToInt16(objField) == NullShort)
{
ret = objDBNull;
}
}
else if (objField is int)
{
if (Convert.ToInt32(objField) == NullInteger)
{
ret = objDBNull;
}
}
else if (objField is Single)
{
if (Convert.ToSingle(objField) == NullSingle)
{
ret = objDBNull;
}
}
else if (objField is double)
{
if (Convert.ToDouble(objField) == NullDouble)
{
ret = objDBNull;
}
}
else if (objField is decimal)
{
if (Convert.ToDecimal(objField) == NullDecimal)
{
ret = objDBNull;
}
}
else if (objField is DateTime)
{
if (Convert.ToDateTime(objField) == NullDate.Date)
{
ret = objDBNull;
}
}
else if (objField is string)
{
if (objField == null)
{
ret = objDBNull;
}
}
else if (objField is bool)
{
if (Convert.ToBoolean(objField) == NullBoolean)
{
ret = objDBNull;
}
}
else if (objField is Guid)
{
if (((Guid)objField).Equals(NullGuid))
{
ret = objDBNull;
}
}
return ret;
}
public static bool IsNull(object objField)
{
bool ret;
if (objField != null)
{
if (objField is int)
{
ret = objField.Equals(NullInteger);
}
else if (objField is Single)
{
ret = objField.Equals(NullSingle);
}
else if (objField is double)
{
ret = objField.Equals(NullDouble);
}
else if (objField is decimal)
{
ret = objField.Equals(NullDecimal);
}
else if (objField is DateTime)
{
DateTime objDate = Convert.ToDateTime(objField);
ret = objDate.Equals(NullInteger);
}
else if (objField is string)
{
ret = objField.Equals(NullString);
}
else if (objField is bool)
{
ret = objField.Equals(NullBoolean);
}
else if (objField is Guid)
{
ret = objField.Equals(NullGuid);
}
else
{
ret = false;
}
}
else
{
ret = true;
}
return ret;
}
}
}
后记:
这是在看DNN时,看到的两个类: Null与CBO。总觉得DB类中的Get方法是一个比较麻烦的方法,空数据也比较令人头痛,有了这两个类,可能会对这两个方面有帮助。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构