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 WebApplication1
{
/// <summary>
/// 根据类型关键字取得相应的对象。
/// 为什么没有用DataTable或DataSet来填充对象的方法。
/// </summary>
public class CBO
{
public CBO()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
/// <summary>
/// 返回存储某类型的所有属性的集合。
/// </summary>
/// <param name="objType">类型(类、接口、枚举等)</param>
/// <returns>属性集合</returns>
public static ArrayList GetPropertyInfo(Type objType)
{
// 存储属性的集合,并试图从缓存中查找关于objType类型的属性,以期填充类型。
ArrayList objProperties = (ArrayList)DataCache.GetCache(objType.FullName);
// 如果属性集合为空
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];
if (dr != null)
{
int count = objProperties.Count;
// 遍历每一个属性
for (int intProperty = 0; intProperty < count; intProperty++)
{
arrOrdinals[intProperty] = -1;
try
{
// 设置该属性对应dr中的索引号 , 如果没有,设置为-1
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 count = objProperties.Count;
for (int intProperty = 0; intProperty < count; intProperty++)
{
// 取得第intProperty个属性
objPropertyInfo = (PropertyInfo)objProperties[intProperty];
// 如果该属性允许写入
if (objPropertyInfo.CanWrite)
{
// 将objValue设置为空 根据objPropertyInfo.PropertyType值来取得空值
objValue = Null.SetNull(objPropertyInfo);
// 如果索引大于-1
if (arrOrdinals[intProperty] != -1)
{
// 判断dr的第arrOrdinals[intProperty]格元素是空
if (Information.IsDBNull(dr.GetValue(arrOrdinals[intProperty])))
{
// 将给定对象的属性值设置为给定值[即相应的空值]
objPropertyInfo.SetValue(objObject, objValue, null);
}
// 如果不是空
else
{
try
{
// 将给定对象的属性值设置为给定值
objPropertyInfo.SetValue(objObject, dr.GetValue(arrOrdinals[intProperty]), null);
}
catch
{
// 如果设置不成功
try
{
// 取得相应数据类型
objPropertyType = objPropertyInfo.PropertyType;
// BaseType:获取当前 System.Type 直接从中继承的类型
// 如果类型是枚举
if (objPropertyType.BaseType.Equals(typeof(System.Enum)))
{
// 判断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);
}
}
// 如果不是枚举类型
else
{
objPropertyInfo.SetValue(objObject, Convert.ChangeType(dr.GetValue(arrOrdinals[intProperty]), objPropertyType), 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;
int intProperty;
// 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;
int intProperty;
// 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;
}
public static XmlDocument Serialize(object objObject)
{
// 将对象序列化到 XML 文档中和从 XML 文档中反序列化对象。System.Xml.Serialization.XmlSerializer 使您得以控制如何将对象编码到 XML 中。
XmlSerializer objXmlSerializer = new XmlSerializer(objObject.GetType());
StringBuilder objStringBuilder = new StringBuilder();
// 表示可以编写一个有序字符系列的编写器。
TextWriter objTextWriter = new StringWriter(objStringBuilder);
// 使用指定的 System.Xml.XmlWriter 序列化指定的 System.Object 并将 XML 文档写入文件,从而引用指定的命名空间。
objXmlSerializer.Serialize(objTextWriter, objObject);
// 实现从字符串进行读取的 System.IO.TextReader。
StringReader objStringReader = new StringReader(objTextWriter.ToString());
DataSet objDataSet = new DataSet();
// 将数据读入到DataSet中
objDataSet.ReadXml(objStringReader);
XmlDocument xmlSerializedObject = new XmlDocument();
// LoadXml:从指定的字符串加载 XML 文档。
// GetXml:返回存储在 System.Data.DataSet 中的数据的 XML 表示形式
// 加载DataSet中的数据
xmlSerializedObject.LoadXml(objDataSet.GetXml());
return xmlSerializedObject;
}
public static object CloneObject(object ObjectToClone)
{
try
{
// 创建一个与ObjectToClone类型相同的对象
object newObject = Reflection.CreateObject(ObjectToClone.GetType().AssemblyQualifiedName, ObjectToClone.GetType().AssemblyQualifiedName);
// 取得newObject对象类型的属性集合
ArrayList props = GetPropertyInfo(newObject.GetType());
// 取得ObjectToClone对象类型的属性集合
ArrayList cloneArr = GetPropertyInfo(ObjectToClone.GetType());
// 取得属性的数量
int count = cloneArr.Count;
for (int i = 0; i < count; i++)
{
// 取得第i个属性对象
PropertyInfo p = (PropertyInfo)cloneArr[i];
// GetInterface:当在派生类中重写时,搜索指定接口,指定是否要执行区分大小写的搜索。
Type ICloneType = p.PropertyType.GetInterface("ICloneable", true);
// 如果属性可以写入
if (((PropertyInfo)props[i]).CanWrite)
{
// 如果类型不为空
if (ICloneType != null)
{
ICloneable IClone = (ICloneable)p.GetValue(ObjectToClone, null);
((PropertyInfo)props[i]).SetValue(newObject, IClone.Clone(), null);
}
else
{
((PropertyInfo)props[i]).SetValue(newObject, p.GetValue(ObjectToClone, null), null);
}
Type IEnumerableType = p.PropertyType.GetInterface("IEnumerable", true);
if (IEnumerableType != null)
{
IEnumerable IEnum = (IEnumerable)p.GetValue(ObjectToClone, null);
Type IListType = ((PropertyInfo)props[i]).PropertyType.GetInterface("IList", true);
Type IDicType = ((PropertyInfo)props[i]).PropertyType.GetInterface("IDictionary", true);
int j = 0;
if (IListType != null)
{
IList list = (IList)((PropertyInfo)props[i]).GetValue(newObject, null);
foreach (object obj in IEnum)
{
ICloneType = obj.GetType().GetInterface("ICloneable", true);
if (ICloneType != null)
{
ICloneable tmpClone = (ICloneable)obj;
list[j] = tmpClone.Clone();
j += 1;
}
}
}
else
{
if (IDicType != null)
{
IDictionary dic = (IDictionary)((PropertyInfo)props[i]).GetValue(newObject, null);
j = 0;
foreach(DictionaryEntry de in IEnum)
{
ICloneType = de.Value.GetType().GetInterface("ICloneable", true);
if (ICloneType != null)
{
ICloneable tmpClone = (ICloneable)de.Value;
}
j += 1;
}
}
}
}
else
{
}
}
}
return newObject;
}
catch (Exception exc)
{
Reflection.LogException(exc);
return null;
}
}
}
}