예제 #1
0
        /// <summary>
        /// 将ExcelDataRow快速转换为指定类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataRow"></param>
        /// <returns></returns>
        public static T FastConvert <T>(ExcelDataRow dataRow)
        {
            //利用表达式树,动态生成委托并缓存,得到接近于硬编码的性能
            //最终生成的代码近似于(假设T为Person类)
            //Func<ExcelDataRow,Person>
            //      new Person(){
            //          Name = Convert(ChangeType(dataRow.DataCols.SingleOrDefault(c=>c.PropertyName == prop.Name).ColValue,prop.PropertyType),prop.ProertyType),
            //          Age = Convert(ChangeType(dataRow.DataCols.SingleOrDefault(c=>c.PropertyName == prop.Name).ColValue,prop.PropertyType),prop.ProertyType)
            //      }
            // }

            string propertyNames = string.Empty;

            dataRow.DataCols.ForEach(c => propertyNames += c.PropertyName + "_");
            var key = typeof(T).FullName + "_" + propertyNames.Trim('_');


            if (!Table.ContainsKey(key))
            {
                List <MemberBinding> memberBindingList = new List <MemberBinding>();

                MethodInfo singleOrDefaultMethod = typeof(Enumerable)
                                                   .GetMethods()
                                                   .Single(m => m.Name == "SingleOrDefault" && m.GetParameters().Count() == 2)
                                                   .MakeGenericMethod(new[] { typeof(ExcelDataCol) });

                foreach (var prop in typeof(T).GetProperties())
                {
                    Expression <Func <ExcelDataCol, bool> > lambdaExpr = c => c.PropertyName == prop.Name;

                    MethodInfo changeTypeMethod = typeof(ExpressionMapper).GetMethods().Where(m => m.Name == "ChangeType").First();

                    Expression expr =
                        Expression.Convert(
                            Expression.Call(changeTypeMethod
                                            , Expression.Property(
                                                Expression.Call(
                                                    singleOrDefaultMethod
                                                    , Expression.Constant(dataRow.DataCols)
                                                    , lambdaExpr)
                                                , typeof(ExcelDataCol), "ColValue"), Expression.Constant(prop.PropertyType))
                            , prop.PropertyType);

                    memberBindingList.Add(Expression.Bind(prop, expr));
                }

                MemberInitExpression memberInitExpression   = Expression.MemberInit(Expression.New(typeof(T)), memberBindingList.ToArray());
                Expression <Func <ExcelDataRow, T> > lambda = Expression.Lambda <Func <ExcelDataRow, T> >(memberInitExpression, new ParameterExpression[]
                {
                    Expression.Parameter(typeof(ExcelDataRow), "p")
                });

                Func <ExcelDataRow, T> func = lambda.Compile();//拼装是一次性的
                Table[key] = func;
            }
            var ss = (Func <ExcelDataRow, T>)Table[key];

            return(((Func <ExcelDataRow, T>)Table[key]).Invoke(dataRow));
        }
예제 #2
0
 /// <summary>
 /// 设置Excel行的校验结果
 /// </summary>
 /// <param name="row"></param>
 /// <param name="isValid"></param>
 /// <param name="col"></param>
 /// <param name="errorMsg"></param>
 public static void SetNotValid(this ExcelDataRow row, bool isValid, ExcelDataCol dataCol, string errorMsg)
 {
     if (!isValid)
     {
         row.IsValid   = false;
         row.ErrorMsg += dataCol.ColName + errorMsg + ";";
     }
 }
예제 #3
0
        /// 直接反射
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="row"></param>
        /// <returns></returns>
        //public static T Convert<T>(this ExcelDataRow row)
        //{
        //    return Convert<T>(row, GetValue);
        //}

        /// <summary>
        /// 将ExcelDataRow转换为指定类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="row"></param>
        /// <returns></returns>
        private static T Convert <T>(this ExcelDataRow row, Func <ExcelDataRow, Type, string, object> func)
        {
            Type   t = typeof(T);
            object o = Activator.CreateInstance(t);

            t.GetProperties().ToList().ForEach(p =>
            {
                if (p.IsDefined(typeof(ColNameAttribute)))
                {
                    p.SetValue(o, func(row, p.PropertyType, p.GetCustomAttribute <ColNameAttribute>().ColName));
                }
            });

            return((T)o);
        }
예제 #4
0
        /// <summary>
        /// 利用反射将ExcelDataRow转换为制定类型,性能较差
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="row"></param>
        /// <returns></returns>
        //public static T ConvertByRefelection<T>(this ExcelDataRow row)
        //{
        //    Type t = typeof(T);
        //    object o = Activator.CreateInstance(t);
        //    t.GetProperties().ToList().ForEach(p => {
        //        if (p.IsDefined(typeof(ColNameAttribute)))
        //        {
        //            ExcelDataCol col = row.DataCols.SingleOrDefault(c => c.ColName == p.GetCustomAttribute<ColNameAttribute>().ColName);

        //            if (col != null)
        //            {
        //                p.SetValue(o, ExpressionMapper.ChangeType(col.ColValue, p.PropertyType));
        //            }
        //        }
        //    });

        //    return (T)o;
        //}

        /// <summary>
        /// 利用表达式树,将ExcelDataRow快速转换为指定类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="row"></param>
        /// <returns></returns>
        public static T FastConvert <T>(this ExcelDataRow row)
        {
            return(ExpressionMapper.FastConvert <T>(row));
        }