支持 Nullable的DataReader高效转实体代码

using System;using System;using System.Collections.Generic;using System.Data;using System.Linq;using System.Linq.Expressions;using System.Text;using System.Threading.Tasks;////2015-02-15//1.修改记录增加了对 Nullable<int> 即int? 这种类型的支持namespace System.Data{/// <summary>/// DataReader高性能读取帮肋类/// </summary>public class DataReaderFullHelper{/// <summary>/// 读取DataReader填充数据/// </summary>/// <typeparam name="T">实体数据体</typeparam>/// <param name="reader" />IDataReader对像/// <param name="autoDisposeReader" />是否在读取完成后自动释放DataReader/// <returns></returns>public List<t> FullListFromList<t>(IDataReader reader, bool autoDisposeReader = true) where T : new(){List<t> result = new List<t>();try{Dictionary<int datacolumn=""> columnDics = new Dictionary<int datacolumn="">();//表达式字典委托Dictionary<int, Action<t idatareader="">> actionDics = new Dictionary<int, Action<t idatareader="">>();//数据实体类型Type entityType = typeof(T);var perDic = entityType.GetProperties().ToDictionary(p => p.Name);//生成表头for (int i = 0; i < reader.FieldCount; i++){DataColumn col = new DataColumn(){ColumnName = reader.GetName(i),DataType = reader.GetFieldType(i),Namespace = reader.GetDataTypeName(i)};//添加列columnDics.Add(i, col);//如果包含列则进行添加if (perDic.ContainsKey(col.ColumnName)){//获取字典值var perty = perDic[col.ColumnName];bool isnullable = IsNullableType(perty.PropertyType);if (isnullable){actionDics.Add(i, SetValueToEntity<t>(i, perty, col.DataType, isnullable));}else{actionDics.Add(i, SetValueToEntity<t>(i, col.ColumnName, col.DataType));}}}//查询读取项while (reader.Read()){T objT = new T();//添加到集合result.Add(objT);//填充属性值foreach (var item in actionDics){//判断字段是否为nullif (!reader.IsDBNull(item.Key)){//设置属性值item.Value(objT, reader);}else{//null处理}}}}finally{//释放dataReaderif (reader != null && autoDisposeReader){reader.Close();reader.Dispose();}}return result;}#region 设置读取实体属性值/// <summary>/// nullable类型/// </summary>private Type nullableType = typeof(Nullable<>);/// <summary>/// 判断一个类型是否为 Nullable 值类型/// </summary>/// <param name="theType" />值类型数据/// <returns>是ull</returns>public bool IsNullableType(Type theType){return (theType.IsGenericType && theType.GetGenericTypeDefinition().Equals(nullableType));}/// <summary>/// 返回null/// </summary>/// <typeparam name="T">值类型</typeparam>/// <param name="par" />值数据/// <returns></returns>public static Func<T, Nullable<t>> ValueAction<t>() where T : struct{Func<T, Nullable<t>> fun = val => new Nullable<t>(val);return fun;}/// <summary>/// 获取指定索引的数据并且返回调用委托/// </summary>/// <typeparam name="T">实体类类型</typeparam>/// <typeparam name="T1">结果类型</typeparam>/// <param name="index" />当前对应在DataReader中的索引/// <param name="ProPertyName" />对应实体类属性名/// <param name="FieldType" />字段类型/// <returns>返回通过调用的委托</returns>public Action<t idatarecord=""> SetValueToEntity<t>(int index, string ProPertyName, Type FieldType){Type datareader = typeof(IDataRecord);IDataReader a;var Mdthods = datareader.GetMethods().Where(p => p.ReturnType == FieldType && p.Name.StartsWith("Get") && p.GetParameters().Where(n => n.ParameterType == typeof(int)).Count() == 1);//处理GetString方法if (FieldType == typeof(string)) {Mdthods = new System.Reflection.MethodInfo[] { datareader.GetMethod("GetString") };}//获取调用方法System.Reflection.MethodInfo Method = null;if (Mdthods.Count() > 0){Method = Mdthods.FirstOrDefault();}else{throw new EntryPointNotFoundException("没有从DataReader找到合适的取值方法");}ParameterExpression e = Expression.Parameter(typeof(T), "e");ParameterExpression r = Expression.Parameter(datareader, "r");//常数表达式ConstantExpression i = Expression.Constant(index);MemberExpression ep = Expression.PropertyOrField(e, ProPertyName);MethodCallExpression call = Expression.Call(r, Method, i);//instance.Property = value 这名话是重点BinaryExpression assignExpression = Expression.Assign(ep, call);var ex = Expression.Lambda(assignExpression, e, r);Expression<Action<t idatarecord="">> resultEx = Expression.Lambda<Action<t idatarecord="">>(assignExpression, e, r);Action<t idatarecord=""> result = resultEx.Compile();return result;}/// <summary>/// 获取指定索引的数据并且返回调用委托,用于处理Nullable值类型值/// </summary>/// <typeparam name="T">实体类类型</typeparam>/// <typeparam name="T1">结果类型</typeparam>/// <param name="index" />当前对应在DataReader中的索引/// <param name="ProPertyName" />对应实体类属性名/// <param name="FieldType" />字段类型/// <param name="isNnullable" />是否null值/// <returns>返回通过调用的委托</returns>public Action<t idatarecord=""> SetValueToEntity<t>(int index, System.Reflection.PropertyInfo ProPerty, Type FieldType, bool isNnullable){Action<t idatarecord=""> result;//不是nullable正常返回if (!isNnullable){result = SetValueToEntity<t>(index, ProPerty.Name, FieldType);}else{//是 nullable 需要重新计算Type datareader = typeof(IDataRecord);//获取值类型var types = ProPerty.PropertyType.GetGenericArguments();Type valType = null;if (types.Length > 0){valType = types[0];}//这个方法是获取值的功能var Mdthods = datareader.GetMethods().Where(p => p.ReturnType == valType && p.Name.StartsWith("Get") && p.GetParameters().Where(n => n.ParameterType == typeof(int)).Count() == 1);//处理GetString方法if (FieldType == typeof(string)){Mdthods = new System.Reflection.MethodInfo[] { datareader.GetMethod("GetString") };}//获取调用方法System.Reflection.MethodInfo Method = null;if (Mdthods.Count() > 0){Method = Mdthods.FirstOrDefault();}else{throw new EntryPointNotFoundException("没有从DataReader找到合适的取值方法");}//处理表达式ParameterExpression e = Expression.Parameter(typeof(T), "e");ParameterExpression r = Expression.Parameter(datareader, "r");//常数表达式ConstantExpression i = Expression.Constant(index);MemberExpression ep = Expression.PropertyOrField(e, ProPerty.Name);//调用dataReader的取值方法MethodCallExpression call = Expression.Call(r, Method, i);#region Nullable//Nullable处理var meth = GetType().GetMethod("ValueAction");var genthod = meth.MakeGenericMethod(valType);//调用方法生成委托Delegate thod = (Delegate)genthod.Invoke(null, null);//将委托邦定到表达式树 new Nullable<int>(121);MethodCallExpression callNullable = Expression.Call(thod.Method, call);#endregion//处理值BinaryExpression assignExpression = Expression.Assign(ep, callNullable);var ex = Expression.Lambda(assignExpression, e, r);Expression<Action<t idatarecord="">> resultEx = Expression.Lambda<Action<t idatarecord="">>(assignExpression, e, r);result = resultEx.Compile();}return result;}/// <summary>/// 获取指定索引的数据并且返回调用委托/// </summary>/// <typeparam name="T">实体类类型</typeparam>/// <typeparam name="T1">结果类型</typeparam>/// <param name="index" />当前对应在DataReader中的索引/// <param name="ProPertyName" />对应实体类属性名/// <param name="canreturn" />是否有返回值/// <returns>返回通过调用的委托</returns>public Func<t idatareader="" t1=""> SetValueToEntity<t t1="">(int index, string ProPertyName){Type datareader = typeof(IDataRecord);var Mdthods = datareader.GetMethods().Where(p => p.ReturnType == typeof(T1));//获取调用方法System.Reflection.MethodInfo Method = null;if (Mdthods.Count() > 0){Method = Mdthods.FirstOrDefault();}else{throw new EntryPointNotFoundException("没有从DataReader找到合适的取值方法");}ParameterExpression e = Expression.Parameter(typeof(T), "e");ParameterExpression r = Expression.Parameter(datareader, "r");//常数表达式ConstantExpression i = Expression.Constant(index);MemberExpression ep = Expression.PropertyOrField(e, ProPertyName);MethodCallExpression call = Expression.Call(r, Method, i);//instance.Property = value 这句话是重点BinaryExpression assignExpression = Expression.Assign(ep, call);var ex = Expression.Lambda(assignExpression, e, r);Expression<Func<t idatarecord="" t1="">> resultEx = Expression.Lambda<Func<t idatarecord="" t1="">>(assignExpression, e, r);Func<t idatarecord="" t1=""> result = resultEx.Compile();return result;}/// <summary>/// 获取设置DataRead与实体类指定列的表达式/// </summary>/// <typeparam name="T">实体类类型</typeparam>/// <typeparam name="T1">结果类型</typeparam>/// <param name="index" />当前对应在DataReader中的索引/// <param name="ProPertyName" />对应实体类属性名/// <param name="DataReaderGetValueMethodName" />调用DataReader中获取值的方法名如:GetString/// <returns>返回通过调用的委托</returns>public Func<t idatareader="" t1=""> SetValueToEntity<t t1="">(int index, string ProPertyName, string DataReaderGetValueMethodName){ParameterExpression e = Expression.Parameter(typeof(T), "e");ParameterExpression r = Expression.Parameter(typeof(IDataRecord), "r");//常数表达式ConstantExpression i = Expression.Constant(index);MemberExpression ep = Expression.PropertyOrField(e, ProPertyName);MethodCallExpression call = Expression.Call(r, typeof(IDataRecord).GetMethod(DataReaderGetValueMethodName, new Type[] { typeof(int) }), i);//instance.Property = value 这名话是重点BinaryExpression assignExpression = Expression.Assign(ep, call);var ex = Expression.Lambda(assignExpression, e, r);Expression<Func<t idatarecord="" t1="">> resultEx = Expression.Lambda<Func<t idatarecord="" t1="">>(assignExpression, e, r);Func<t idatarecord="" t1=""> result = resultEx.Compile();return result;}/// <summary>/// 获取设置属性值的委托/// </summary>/// <typeparam name="T">当关类型名</typeparam>/// <typeparam name="T1">返回值</typeparam>/// <param name="index" />索引/// <param name="Entity" />实体对像/// <param name="ProPertyName" />属性名/// <param name="DataReaderGetValueMethodName" />DataReader获取值方法名 如:"GetString"/// <returns></returns>public Func<t idatarecord="" t1="" int=""> SetPropertyValue<t t1="">(int index, T Entity, string ProPertyName, string DataReaderGetValueMethodName){//(e, r, index) => (e.bookname = r.GetString(index))ParameterExpression e = Expression.Parameter(typeof(T), "e");ParameterExpression r = Expression.Parameter(typeof(IDataRecord), "r");ParameterExpression i = Expression.Parameter(typeof(int), "index");MemberExpression ep = Expression.PropertyOrField(e, ProPertyName);MethodCallExpression call = Expression.Call(r, typeof(IDataRecord).GetMethod(DataReaderGetValueMethodName, new Type[] { typeof(int) }), i);//instance.Property = value 这名话是重点BinaryExpression assignExpression = Expression.Assign(ep, call);var ex = Expression.Lambda(assignExpression, e, r, i);Expression<Func<t idatarecord="" t1="" int="">> resultEx = Expression.Lambda<Func<t idatarecord="" t1="" int="">>(assignExpression, e, r, i);Func<t idatarecord="" t1="" int=""> result = resultEx.Compile();return result;}/// <summary>/// ?url=CdGxWD3l5r9H84NPWRSBFtNkea0hn5g0YujI3AIIPUO0W6g4OHxeunQN6qW2Awq2noM2Mfnj1GrD3FOOagamtwIo67ZVK7M6hj_QiwfEJX7/// sdd = sdd.Where(s => s.SKUCoding.Split('-').Contains(t));/// </summary>/// <typeparam name="T"></typeparam>/// <param name="entity" />/// <param name="propertyname" />/// <param name="value" />/// <returns></returns>private IEnumerable<t> SearchTcontains<t>(IQueryable<t> entity, string propertyname, string value)// where T : EntityObject{// NorthwindEntities en = new NorthwindEntities();ParameterExpression pe = Expression.Parameter(typeof(T), "c");MemberExpression me = Expression.Property(pe, "CustomerID");ConstantExpression ce = Expression.Constant(value);Expression right = Expression.Call(me,//typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),ce);Expression<Func<t bool="">> p = Expression.Lambda<Func<t bool="">>(right, pe);// IEnumerable<t> ems = en.CreateQuery<t>(Plural<t>()).Where(p);// return ems as IEnumerable<t>;return null;}#endregion}/// <summary>/// DataReader扩展方法/// </summary>public static class DataReaderReadExtend{/// <summary>/// 实体帮助类/// </summary>private static DataReaderFullHelper hepler = new DataReaderFullHelper();/// <summary>/// 读取Data的扩展方法/// </summary>/// <typeparam name="T">实体数据体</typeparam>/// <param name="reader" />IDataReader对像/// <param name="autoDisposeReader" />是否在读取完成后自动释放DataReader/// <returns></returns>public static List<t> ReaderToList<t>(this IDataReader reader, bool autoDisposeReader = true) where T : new(){return hepler.FullListFromList<t>(reader, autoDisposeReader);}}}</t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></int></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></t></int></int></t></t></t></t></int>

使用方法:

其实你已经错过了旅行的意义。

支持 Nullable的DataReader高效转实体代码

相关文章:

你感兴趣的文章:

标签云: