阅读背景:

支持 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)
                    {
                        //断定字段是不是为null
                        if (!reader.IsDBNull(item.Key))
                        {
                            //设置属性值
                            item.Value(objT, reader);
                        }
                        else
                        {
                            //null处置
                        }
                    }
                }
            }
            finally
            {
                //释放dataReader
                if (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>
        /// https://zhidao.baidu.com/link?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>using System;

using System;
using System.Collecti




你的当前访问异常,请进行认证后继续阅读剩余内容。

分享到: