usingSystem;
usingSystem.Collections.Generic;
usingSystem.Data;
usingSystem.Data.Common;
usingSystem.Reflection;
///
/// 实体阅读器类,可以从DataTable中或者DbDataReader的实例中将数据转换成对应的示例
/// 作者:周公
/// 日期:2011-07-17
///修改日期:2011-07-21
/// 博客地址:http://blog.csdn.net/zhoufoxcn 或http://zhoufoxcn.blog.51cto.com
/// 说明:(1)任何人都可以免费使用,请尽量保持此段说明。
/// (2)这个版本还不是最终版本,有任何意见或建议请到http://weibo.com/zhoufoxcn处留言。
///
publicsealedclassEntityReader
{
privateconstBindingFlags BindingFlag = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
//将类型与该类型所有的可写且未被忽略属性之间建立映射
privatestaticDictionary> propertyMappings =newDictionary>();
//存储Nullable与T的对应关系
privatestaticDictionary genericTypeMappings =newDictionary();
staticEntityReader()
{
genericTypeMappings.Add(typeof(Byte?),typeof(Byte));
genericTypeMappings.Add(typeof(SByte?),typeof(SByte));
genericTypeMappings.Add(typeof(Char?),typeof(Char));
genericTypeMappings.Add(typeof(Boolean?),typeof(Boolean));
genericTypeMappings.Add(typeof(Guid?),typeof(Guid));
genericTypeMappings.Add(typeof(Int16),typeof(Int16));
genericTypeMappings.Add(typeof(UInt16),typeof(UInt16));
genericTypeMappings.Add(typeof(Int32),typeof(Int32));
genericTypeMappings.Add(typeof(UInt32),typeof(UInt32));
genericTypeMappings.Add(typeof(Int64),typeof(Int64));
genericTypeMappings.Add(typeof(UInt64),typeof(UInt64));
genericTypeMappings.Add(typeof(Single),typeof(Single));
genericTypeMappings.Add(typeof(Double),typeof(Double));
genericTypeMappings.Add(typeof(Decimal),typeof(Decimal));
genericTypeMappings.Add(typeof(DateTime),typeof(DateTime));
genericTypeMappings.Add(typeof(TimeSpan),typeof(TimeSpan));
genericTypeMappings.Add(typeof(Enum),typeof(Enum));
}
///
/// 将DataTable中的所有数据转换成List>T
///
/// DataTable中每条数据可以转换的数据类型
/// 包含有可以转换成数据类型T的数据集合
///
publicstaticList GetEntities(DataTable dataTable) where T :new()
{
if(dataTable ==null)
{
thrownewArgumentNullException("dataTable");
}
//如果T的类型满足以下条件:字符串、ValueType或者是Nullable
if(typeof(T)==typeof(string)||typeof(T).IsValueType)
{
returnGetSimpleEntities(dataTable);
}
else
{
returnGetComplexEntities(dataTable);
}
}
///
/// 将DbDataReader中的所有数据转换成List>T
///
/// DbDataReader中每条数据可以转换的数据类型
/// 包含有可以转换成数据类型T的DbDataReader实例
///
publicstaticList GetEntities(DbDataReader reader) where T :new()
{
List list = newList();
if(reader ==null)
{
thrownewArgumentNullException("reader");
}
//如果T的类型满足以下条件:字符串、ValueType或者是Nullable
if(typeof(T) ==typeof(string) ||typeof(T).IsValueType)
{
returnGetSimpleEntities(reader);
}
else
{
returnGetComplexEntities(reader);
}
}
///
/// 从DataTable中将每一行的第一列转换成T类型的数据
///
/// 要转换的目标数据类型
/// 包含有可以转换成数据类型T的数据集合
///
privatestaticList GetSimpleEntities(DataTable dataTable) where T :new()
{
List list = newList();
foreach(DataRow rowindataTable.Rows)
{
list.Add((T)GetValueFromObject(row[0], typeof(T)));
}
returnlist;
}
///
/// 将指定的 Object 的值转换为指定类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
/// 要转换的目标数据类型
///
privatestaticobjectGetValueFromObject(objectvalue, Type targetType)
{
if(targetType ==typeof(string))//如果要将value转换成string类型
{
returnGetString(value);
}
elseif(targetType.IsGenericType)//如果目标类型是泛型
{
returnGetGenericValueFromObject(value, targetType);
}
else//如果是基本数据类型(包括数值类型、枚举和Guid)
{
returnGetNonGenericValueFromObject(value, targetType);
}
}
///
/// 从DataTable中读取复杂数据类型集合
///
/// 要转换的目标数据类型
/// 包含有可以转换成数据类型T的数据集合
///
privatestaticList GetComplexEntities(DataTable dataTable) where T :new()
{
if(!propertyMappings.ContainsKey(typeof(T)))
{
GenerateTypePropertyMapping(typeof(T));
}
List list = newList();
Dictionary properties = propertyMappings[typeof(T)];
//Dictionary propertyColumnOrdinalMapping = GetPropertyColumnIndexMapping(dataTable.Columns, properties);
T t;
foreach(DataRow rowindataTable.Rows)
{
t = newT();
foreach(KeyValuePair iteminproperties)
{
//int ordinal = -1;
//if (propertyColumnOrdinalMapping.TryGetValue(item.Key, out ordinal))
//{
// item.Value.SetValue(t, GetValueFromObject(row[ordinal], item.Value.PropertyType), null);
//}
item.Value.SetValue(t, GetValueFromObject(row[item.Key], item.Value.PropertyType), null);
}
list.Add(t);
}
returnlist;
}
///
/// 从DbDataReader的实例中读取复杂的数据类型
///
/// 要转换的目标类
/// DbDataReader的实例
///
privatestaticList GetComplexEntities(DbDataReader reader) where T :new()
{
if(!propertyMappings.ContainsKey(typeof(T)))//检查当前是否已经有该类与类的可写属性之间的映射
{
GenerateTypePropertyMapping(typeof(T));
}
List list = newList();
Dictionary properties = propertyMappings[typeof(T)];
//Dictionary propertyColumnOrdinalMapping = GetPropertyColumnIndexMapping(reader, properties);
T t;
while(reader.Read())
{
t = newT();
foreach(KeyValuePair iteminproperties)
{
//int ordinal = -1;
//if (propertyColumnOrdinalMapping.TryGetValue(item.Key, out ordinal))
//{
// item.Value.SetValue(t, GetValueFromObject(reader[ordinal], item.Value.PropertyType), null);
//}
item.Value.SetValue(t, GetValueFromObject(reader[item.Key], item.Value.PropertyType), null);
}
list.Add(t);
}
returnlist;
}
///
/// 从DbDataReader的实例中读取简单数据类型(String,ValueType)
///
/// 目标数据类型
/// DbDataReader的实例
///
privatestaticList GetSimpleEntities(DbDataReader reader)
{
List list = newList();
while(reader.Read())
{
list.Add((T)GetValueFromObject(reader[0], typeof(T)));
}
returnlist;
}
///
/// 将Object转换成字符串类型
///
/// object类型的实例
///
privatestaticobjectGetString(objectvalue)
{
returnConvert.ToString(value);
}
///
/// 将指定的 Object 的值转换为指定枚举类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
///
///
privatestaticobjectGetEnum(objectvalue, Type targetType)
{
returnEnum.Parse(targetType, value.ToString());
}
///
/// 将指定的 Object 的值转换为指定枚举类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
///
privatestaticobjectGetBoolean(objectvalue)
{
if(valueisBoolean)
{
returnvalue;
}
else
{
bytebyteValue = (byte)GetByte(value);
if(byteValue == 0)
{
returnfalse;
}
else
{
returntrue;
}
}
}
///
/// 将指定的 Object 的值转换为指定枚举类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
///
privatestaticobjectGetByte(objectvalue)
{
if(valueisByte)
{
returnvalue;
}
else
{
returnbyte.Parse(value.ToString());
}
}
///
/// 将指定的 Object 的值转换为指定枚举类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
///
privatestaticobjectGetSByte(objectvalue)
{
if(valueisSByte)
{
returnvalue;
}
else
{
returnSByte.Parse(value.ToString());
}
}
///
/// 将指定的 Object 的值转换为指定枚举类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
///
privatestaticobjectGetChar(objectvalue)
{
if(valueisChar)
{
returnvalue;
}
else
{
returnChar.Parse(value.ToString());
}
}
///
/// 将指定的 Object 的值转换为指定枚举类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
///
privatestaticobjectGetGuid(objectvalue)
{
if(valueisGuid)
{
returnvalue;
}
else
{
returnnewGuid(value.ToString());
}
}
///
/// 将指定的 Object 的值转换为指定枚举类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
///
privatestaticobjectGetInt16(objectvalue)
{
if(valueisInt16)
{
returnvalue;
}
else
{
returnInt16.Parse(value.ToString());
}
}
///
/// 将指定的 Object 的值转换为指定枚举类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
///
privatestaticobjectGetUInt16(objectvalue)
{
if(valueisUInt16)
{
returnvalue;
}
else
{
returnUInt16.Parse(value.ToString());
}
}
///
/// 将指定的 Object 的值转换为指定枚举类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
///
privatestaticobjectGetInt32(objectvalue)
{
if(valueisInt32)
{
returnvalue;
}
else
{
returnInt32.Parse(value.ToString());
}
}
///
/// 将指定的 Object 的值转换为指定枚举类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
///
privatestaticobjectGetUInt32(objectvalue)
{
if(valueisUInt32)
{
returnvalue;
}
else
{
returnUInt32.Parse(value.ToString());
}
}
///
/// 将指定的 Object 的值转换为指定枚举类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
///
privatestaticobjectGetInt64(objectvalue)
{
if(valueisInt64)
{
returnvalue;
}
else
{
returnInt64.Parse(value.ToString());
}
}
///
/// 将指定的 Object 的值转换为指定枚举类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
///
privatestaticobjectGetUInt64(objectvalue)
{
if(valueisUInt64)
{
returnvalue;
}
else
{
returnUInt64.Parse(value.ToString());
}
}
///
/// 将指定的 Object 的值转换为指定枚举类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
///
privatestaticobjectGetSingle(objectvalue)
{
if(valueisSingle)
{
returnvalue;
}
else
{
returnSingle.Parse(value.ToString());
}
}
///
/// 将指定的 Object 的值转换为指定枚举类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
///
privatestaticobjectGetDouble(objectvalue)
{
if(valueisDouble)
{
returnvalue;
}
else
{
returnDouble.Parse(value.ToString());
}
}
///
/// 将指定的 Object 的值转换为指定枚举类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
///
privatestaticobjectGetDecimal(objectvalue)
{
if(valueisDecimal)
{
returnvalue;
}
else
{
returnDecimal.Parse(value.ToString());
}
}
///
/// 将指定的 Object 的值转换为指定枚举类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
///
privatestaticobjectGetDateTime(objectvalue)
{
if(valueisDateTime)
{
returnvalue;
}
else
{
returnDateTime.Parse(value.ToString());
}
}
///
/// 将指定的 Object 的值转换为指定枚举类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
///
privatestaticobjectGetTimeSpan(objectvalue)
{
if(valueisTimeSpan)
{
returnvalue;
}
else
{
returnTimeSpan.Parse(value.ToString());
}
}
///
/// 将Object类型数据转换成对应的可空数值类型表示
///
/// 实现 IConvertible 接口的 Object,或者为 null
/// 可空数值类型
///
privatestaticobjectGetGenericValueFromObject(objectvalue,Type targetType)
{
if(value == DBNull.Value)
{
returnnull;
}
else
{
//获取可空数值类型对应的基本数值类型,如int?->int,long?->long
Type nonGenericType= genericTypeMappings[targetType];
returnGetNonGenericValueFromObject(value, nonGenericType);
}
}
///
/// 将指定的 Object 的值转换为指定类型的值。
///
/// 实现 IConvertible 接口的 Object,或者为 null
/// 目标对象的类型
///
privatestaticobjectGetNonGenericValueFromObject(objectvalue, Type targetType)
{
if(targetType.IsEnum)//因为
{
returnGetEnum(value, targetType);
}
else
{
switch(targetType.Name)
{
case"Byte":returnGetByte(value);
case"SByte":returnGetSByte(value);
case"Char":returnGetChar(value);
case"Boolean":returnGetBoolean(value);
case"Guid":returnGetGuid(value);
case"Int16":returnGetInt16(value) ;
case"UInt16":returnGetUInt16(value);
case"Int32":returnGetInt32(value);
case"UInt32":returnGetUInt32(value);
case"Int64":returnGetInt64(value);
case"UInt64":returnGetUInt64(value);
case"Single":returnGetSingle(value);
case"Double":returnGetDouble(value);
case"Decimal":returnGetDecimal(value);
case"DateTime":returnGetDateTime(value);
case"TimeSpan":returnGetTimeSpan(value);
default:returnnull;
}
}
}
///
/// 获取该类型中属性与数据库字段的对应关系映射
///
///
privatestaticvoidGenerateTypePropertyMapping(Type type)
{
if(type !=null)
{
PropertyInfo[] properties = type.GetProperties(BindingFlag);
Dictionary propertyColumnMapping =newDictionary(properties.Length);
stringdescription =string.Empty;
Attribute[] attibutes = null;
stringcolumnName =string.Empty;
boolignorable =false;
foreach(PropertyInfo pinproperties)
{
ignorable = false;
columnName = string.Empty;
attibutes = Attribute.GetCustomAttributes(p);
foreach(Attribute attributeinattibutes)
{
//检查是否设置了ColumnName属性
if(attribute.GetType() ==typeof(ColumnNameAttribute))
{
columnName = ((ColumnNameAttribute)attribute).ColumnName;
ignorable = ((ColumnNameAttribute)attribute).Ignorable;
break;
}
}
//如果该属性是可读并且未被忽略的,则有可能在实例化该属性对应的类时用得上
if(p.CanWrite&&!ignorable)
{
//如果没有设置ColumnName属性,则直接将该属性名作为数据库字段的映射
if(string.IsNullOrEmpty(columnName))
{
columnName = p.Name;
}
propertyColumnMapping.Add(columnName, p);
}
}
propertyMappings.Add(type, propertyColumnMapping);
}
}
//private static Dictionary GetPropertyColumnIndexMapping(DataColumnCollection dataSource, Dictionary properties)
//{
// Stopwatch watch = new Stopwatch();
// watch.Start();
// Dictionary propertyColumnIndexMapping=new Dictionary(dataSource.Count);
// foreach(KeyValuePair item in properties)
// {
// for (int i = 0; i
// {
// if (item.Key.Equals(dataSource[i].ColumnName, StringComparison.InvariantCultureIgnoreCase))
// {
// propertyColumnIndexMapping.Add(item.Key, i);
// break;
// }
// }
// }
// watch.Stop();
// Debug.WriteLine("Elapsed:" + watch.ElapsedMilliseconds);
// return propertyColumnIndexMapping;
//}
//private static Dictionary GetPropertyColumnIndexMapping(DbDataReader dataSource, Dictionary properties)
//{
// Dictionary propertyColumnIndexMapping = new Dictionary(dataSource.FieldCount);
// foreach (KeyValuePair item in properties)
// {
// for (int i = 0; i
// {
// if (item.Key.Equals(dataSource.GetName(i), StringComparison.InvariantCultureIgnoreCase))
// {
// propertyColumnIndexMapping.Add(item.Key, i);
// continue;
// }
// }
// }
// return propertyColumnIndexMapping;
//}
}
///
/// 自定义属性,用于指示如何从DataTable或者DbDataReader中读取类的属性值
///
publicclassColumnNameAttribute : Attribute
{
///
/// 类属性对应的列名
///
publicstringColumnName {get;set; }
///
/// 指示在从DataTable或者DbDataReader中读取类的属性时是否可以忽略这个属性
///
publicboolIgnorable {get;set; }
///
/// 构造函数
///
/// 类属性对应的列名
publicColumnNameAttribute(stringcolumnName)
{
ColumnName = columnName;
Ignorable = false;
}
///
/// 构造函数
///
/// 指示在从DataTable或者DbDataReader中读取类的属性时是否可以忽略这个属性
publicColumnNameAttribute(boolignorable)
{
Ignorable = ignorable;
}
///
/// 构造函数
///
/// 类属性对应的列名
/// 指示在从DataTable或者DbDataReader中读取类的属性时是否可以忽略这个属性
publicColumnNameAttribute(stringcolumnName,boolignorable)
{
ColumnName = columnName;
Ignorable = ignorable;
}
}