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

前言,此方法利用反射将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

时间: 2024-10-26 08:48:59

DataRow转泛型,利用反射将查询数据直接转成实体的相关文章

hibernate查询部分字段转换成实体bean

//hibernate查询部分字段转换成实体bean /** * 查询线路信息 */ @Override public List<Line> getSimpleLineListByTj(Map<String,Object> paramMap){ Criteria cr=this.getSession().createCriteria(Line.class,"Line"); // cr.setFetchMode("chuTuanInfo", F

利用反射将Datatable、SqlDataReader转换成List模型

1. DataTable转IList 1 public class DataTableToList<T>whereT :new() 2 3 { 4 5 ///<summary> 6 7 ///利用反射将Datatable转换成List模型 8 9 ///</summary> 10 11 ///<param name="dt"></param> 12 13 ///<returns></returns> 1

使用Sql语句快速将数据表转换成实体类

开发过程中经常需要根据数据表编写对应的实体类,下面是使用sql语句快速将数据表转换成对应实体类的代码,使用时只需要将第一行'TableName'引号里面的字母换成具体的表名称就行了: declare @TableName sysname = 'TableName' declare @Result varchar(max) = 'public class ' + @TableName + ' {' select @Result = @Result + ' public ' + ColumnType

JDBC学习笔记(16):利用反射技术奖查询结果封装为对象

1 package com.xxyh.jdbc; 2 import java.lang.reflect.InvocationTargetException; 3 import java.lang.reflect.Method; 4 import java.sql.Connection; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.sql.ResultSetMetaData; 8 i

关于SpringMVC中如何把查询数据全转成String类型

之前,本想与客户商量做几张固定的报表予使用,结果发现客户每个月都需要各种各样的报表,所以我们做了个窗口用于直接执行SQL语句:数据量一开始并不是很大查询出来的数据较少(约1-6W左右),所以刚开始几个月很好用,查询出来的数据直接从页面复制下来贴到Excel做月报表,就这样一年过去了,最近做三期,发现运维人员月底几天特别的忙,数据逾百万(汗),SQL查询语句都要写n多分页.... 伙伴们如此幸苦,还是我来拯救他们吧- 我的解决思路大致如下: A>界面增加查询倒出Excel表按钮(不需要分页,也不需

从数据库查询数据然后拼接成xml文件

<%@page import="java.util.HashSet"%> <%@page import="java.util.Set"%> <%@page import="java.util.List"%> <%@page import="java.net.URLDecoder"%> <%@page import="org.apache.el.lang.Expre

hibernate sql查询后对象转换成实体类

在多表查询的时候使用hibernate的sql查询的时候,一般返回的是object[]数组,或者可以使用 session.createSQLQuery(sql).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);     session. session.createSQLQuery(sql).addEntity(entity.class); /**     * 分页查询sql,sql语句不包含起始记录数和查询记录数     * @pa

jdbc增删改查,利用反射查询

整理自http://blog.csdn.net/yanzi1225627/article/details/26950615,谢谢作者! 本文我的爱点是: 1.利用反射实现数据库数据查询 2.编写一个sql语句,其中的参数用?来代替,然后将参数写到List里 例如使用例子: 1 String sql = "delete from userinfo where username = ?"; 2 List<Object> params = new ArrayList<Obj

利用反射处理多个表结构相同的数据的查询和数据库表的关联

最近做一个项目,需要对人口数据进行查询,但是人口数据分布在不同的街道表中,首先进行了数据表结构的统一,每个数据表以街道名开头,然后其他的名字都一样 前期将各个表中的字段也进行了统一 抽象出一张字典表 将街道编号和街道的名字的首字母连接起来,因为查询的时候是利用街道编号来的,这样可以根据街道标号拼出相对于的街道表的名字,(每个人口相关的表不止一张,因此需要统一):在查询过程中,将查询到的结构返回一个LIST,(不同的表在dao中当然对于不同的类啊,返回来再判断是哪一类),然后利用反射Field[]