码迷,mamicode.com
首页 > 其他好文 > 详细

DataRow转泛型,利用反射将查询数据直接转成实体

时间:2016-07-13 15:39:20      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:

前言,此方法利用反射将DataRow转成实体,由于反射SetValue据说性能不行,大家就看看就行了吧。

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;

namespace WangSql.DBUtility
{
    public class DataMapHelper
    {
        private enum ModelType
        {
            Value,
            String,
            Object,
            Reference
        }
        private static ModelType GetModelType(Type modelType)
        {
            if (modelType.IsValueType)//值类型
            {
                return ModelType.Value;
            }
            else if (modelType == typeof(string))//引用类型 特殊类型处理
            {
                return ModelType.String;
            }
            else if (modelType == typeof(object))//引用类型 特殊类型处理
            {
                return ModelType.Object;
            }
            else//引用类型
            {
                return ModelType.Reference;
            }
        }

        public static List<T> DataTableToList<T>(DataTable table)
        {
            List<T> list = new List<T>();
            foreach (DataRow item in table.Rows)
            {
                list.Add(DataRowToModel<T>(item));
            }
            return list;
        }
        public static T DataRowToModel<T>(DataRow row)
        {
            T model;
            Type type = typeof(T);
            ModelType modelType = GetModelType(type);
            switch (modelType)
            {
                case ModelType.Value://值类型
                    {
                        model = default(T);
                        if (row[0] != null)
                            model = (T)row[0];
                    }
                    break;
                case ModelType.String://引用类型 c#对string也当做值类型处理
                    {
                        model = default(T);
                        if (row[0] != null)
                            model = (T)row[0];
                    }
                    break;
                case ModelType.Object://引用类型 直接返回第一行第一列的值
                    {
                        model = default(T);
                        if (row[0] != null)
                            model = (T)row[0];
                    }
                    break;
                case ModelType.Reference://引用类型
                    {
                        model = System.Activator.CreateInstance<T>();//引用类型 必须对泛型实例化
                        #region MyRegion
                        //获取model中的属性
                        PropertyInfo[] modelPropertyInfos = type.GetProperties();
                        //遍历model每一个属性并赋值DataRow对应的列
                        foreach (PropertyInfo pi in modelPropertyInfos)
                        {
                            //获取属性名称
                            String name = pi.Name;
                            if (row.Table.Columns.Contains(name))
                            {
                                //非泛型
                                if (!pi.PropertyType.IsGenericType)
                                {
                                    if (pi.PropertyType.IsEnum)
                                    {
                                        pi.SetValue(model, row[name], null);
                                    }
                                    else
                                    {
                                        pi.SetValue(model, string.IsNullOrEmpty(row[name].ToString()) ? null : Convert.ChangeType(row[name], pi.PropertyType), null);
                                    }
                                }
                                //泛型Nullable<>
                                else
                                {
                                    Type genericTypeDefinition = pi.PropertyType.GetGenericTypeDefinition();
                                    //model属性是可为null类型,进行赋null值
                                    if (genericTypeDefinition == typeof(Nullable<>))
                                    {
                                        //返回指定可以为 null 的类型的基础类型参数
                                        pi.SetValue(model, string.IsNullOrEmpty(row[name].ToString()) ? null : Convert.ChangeType(row[name], Nullable.GetUnderlyingType(pi.PropertyType)), null);
                                    }
                                }
                            }
                        }
                        #endregion
                    }
                    break;
                default:
                    model = default(T);
                    break;
            }

            return model;
        }

    }
}

 

后话,

1.可以通过缓存提高下性能。

   每次typeof(T)后,将其对象相关信息(泛型属性等)存储起来,下次从缓存读取。

2.对SetValue改进。

   可以使用泛型委托对其赋值。

3.用Emit

 

DataRow转泛型,利用反射将查询数据直接转成实体

标签:

原文地址:http://www.cnblogs.com/deeround/p/5666778.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!