本人大二菜鸟一只,今天在上课期间有个同学看着C#反射的内容说反射没什么用,一时之间也想不到什么更好的例子,就写了个根据泛型类型和游标反射创建List集合的Demo.

首先创建一个用于封装对应数据的entity,代码如下.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test
{
    public class EUserInfo
    {
        public int UserId { get; set; }
        public string UserCode { get; set; }
        public string UserName { get; set; }
        public string UserPwd { get; set; }
        public string Gender { get; set; }

        public override string ToString()
        {
            return "UserId:"+UserId+"|UserCode:"+UserCode+"|UserName:"+UserName+"|UserPwd:"+UserPwd+"|Gender:"+Gender;
        }
    }
}

这里我重写了ToString方法,以便待会儿更直观的看到效果.

接下来创建EUserInfo实体类对应的table,sql如下:

use master
go
if exists (select * from sys.databases where name='reflectDemoDB')
drop database reflectDemoDB
create database reflectDemoDB
go
use reflectDemoDB
go
create table UserInfo(
    UserId int primary key identity,
    UserCode ) not null,
    UserName ) not null,
    UserPwd  ) not null,
    Gender   ) check(Gender in ('男','女'))
)
go
','男')
','男')
','男')

  为了可以方便操作ado对象我这里写了一个工具类DBHelper,代码如下:

  

using System;
using System.Collections.Generic;
using System.Web;
using System.Data.SqlClient;
using System.Data;
using System.Configuration;

namespace Test
{
    /// <summary>
    ///DBHelper:数据库访问操作类
    /// </summary>
    public class DBHelper
    {
        /// <summary>
        /// 更新操作:增,删,改 共用
        /// </summary>
        /// <param name="sql"></param>
        /// <returns>bool</returns>
        public static bool UpdateOpera(string sql,params SqlParameter[] sps)
        {
            SqlCommand cmd = new SqlCommand(sql, Connection);
            //////////////////将配置参数加入到Command中
            cmd.Parameters.AddRange(sps);
            /////////////////
            ;
        }

        /// <summary>
        /// 单个查询操作:返回首行首列数据
        /// </summary>
        /// <param name="sql">查询SQL语句</param>
        /// <returns>object</returns>
        public static object GetScalar(string sql, params SqlParameter[] sps)
        {
            SqlCommand cmd = new SqlCommand(sql, Connection);
            //////////////////将配置参数加入到Command中
            cmd.Parameters.AddRange(sps);
            /////////////////
            return cmd.ExecuteScalar();
        }

        /// <summary>
        /// 多行查询操作:返回SqlDataReader
        /// </summary>
        /// <param name="sql">查询SQL语句</param>
        /// <returns>SqlDataReader</returns>
        public static SqlDataReader GetReader(string sql, params SqlParameter[] sps)
        {
            SqlCommand cmd = new SqlCommand(sql, Connection);
            //////////////////将配置参数加入到Command中
            cmd.Parameters.AddRange(sps);
            /////////////////
            return cmd.ExecuteReader();
        }

        /// <summary>
        /// 多行查询操作:返回DataTable
        /// </summary>
        /// <param name="sql">查询SQL语句</param>
        /// <returns>DataTable</returns>
        public static DataTable GetDataTable(string sql, params SqlParameter[] sps)
        {
            DataTable dt = new DataTable();
            SqlDataAdapter dad = new SqlDataAdapter(sql, Connection);
            //////////////////将配置参数加入到Command中
            dad.SelectCommand.Parameters.AddRange(sps);
            /////////////////
            dad.Fill(dt);
            return dt;
        }

        public static List<string> GetColumnsByTableName(string tableName)
        {
            List<string> columnList = new List<string>();
            string sql = "select name from syscolumns where id=object_id(@tableName)";
            SqlDataReader sdr = GetReader(sql, new SqlParameter("@tableName", tableName));
            while (sdr.Read())
            {
                columnList.Add(sdr["name"].ToString());
            }
            sdr.Close();
            return columnList;
        }

        private static SqlConnection _connection;
        /// <summary>
        /// Connection对象
        /// </summary>
        public static SqlConnection Connection
        {
            get
            {
                string connectionString = "Data Source=.;Initial Catalog=reflectDemoDB;Integrated Security=True";
                if (_connection == null)
                {
                    _connection = new SqlConnection(connectionString);
                    _connection.Open();
                }
                else if (_connection.State == ConnectionState.Closed)
                {
                    _connection.Open();
                }
                else if (_connection.State == ConnectionState.Broken || _connection.State == ConnectionState.Open)
                {
                    _connection.Close();
                    _connection.Open();
                }
                return _connection;
            }
        }
    }
}

  接下来就可以进入主题了,我这里是用一个BaseDao做例子,代码如下:

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Test
{
    public class BaseDao<T>
    {
        /// <summary>
        /// 获取泛型对应的实体类类名当做表名
        /// </summary>
        private static string TableName
        {
            get
            {
                return typeof(T).Name.Replace("E","");
            }
        }
        /// <summary>
        /// 获取泛型对应实体类所有属性
        /// </summary>
        private static PropertyInfo[] Properties { get { return typeof(T).GetProperties(); } }
        /// <summary>
        /// 通用查询所有方法
        /// </summary>
        /// <returns></returns>
        public List<T> GetAll()
        {
            //根据获取的表名拼装出sql语句
            string sql = "select * from " + TableName;
            SqlDataReader sdr = DBHelper.GetReader(sql);
            return CreateInstanceListOfSqlDataReader<T>(sdr);
        }
        private static T CreateInstance<T>(SqlDataReader sdr)
        {
            //或许泛型类所有属性

            //根据泛型T创建它的实例
            T t = (T)Activator.CreateInstance(typeof(T));
            //遍历该类所有属性
            foreach (PropertyInfo pro in Properties)
            {
                //判断属性类型 如果是对应类型就强转进行赋值
                if (pro.PropertyType.Equals(typeof(DateTime)))
                    try
                    {
                        pro.SetValue(t, Convert.ToDateTime(sdr[pro.Name]));//利用游标根据属性名获取对应列值给属性赋值
                    }
                    catch (Exception)
                    {
                        throw new Exception("转换DateTime类型失败,[" + pro.Name + "]字段[value=" + sdr[pro.Name].ToString() + "]格式不正确");
                    }
                else if (pro.PropertyType.Equals(typeof(int)))
                    try
                    {
                        pro.SetValue(t, Convert.ToInt32(sdr[pro.Name]));
                    }
                    catch (Exception)
                    {
                        throw new Exception("转换int类型失败,[" + pro.Name + "]字段[value=" + sdr[pro.Name].ToString() + "]格式不正确");
                    }
                else if (pro.PropertyType.Equals(typeof(double)))
                    try
                    {
                        pro.SetValue(t, Convert.ToDouble(sdr[pro.Name]));
                    }
                    catch (Exception)
                    {
                        throw new Exception("转换Double类型失败,[" + pro.Name + "]字段[value=" + sdr[pro.Name].ToString() + "]格式不正确");
                    }
                else
                    pro.SetValue(t, sdr[pro.Name]);
            }
            return t;
        }
        /// <summary>
        /// 根据游标sdr创建一个所传类型对象集合并返回
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <param name="sdr">游标</param>
        /// <returns></returns>
        private List<T> CreateInstanceListOfSqlDataReader<T>(SqlDataReader sdr)
        {
            List<T> tList = new List<T>();
            while (sdr.Read())
            {
                T t = CreateInstance<T>(sdr);
                tList.Add(t);
            }
            return tList;
        }
    }
}

  BaseDao写好以后我们就可以看看效果了,接下来我们创建一个UserInfoDao,来继承BaseDao,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test
{
    public class UserInfoDao:BaseDao<EUserInfo>{}
}

  然后我们就可以开始测试了,下面是测试代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            UserInfoDao userInfoDao = new UserInfoDao();
            List<EUserInfo> userInfoList = userInfoDao.GetAll();
            foreach (EUserInfo userInfo in userInfoList)
            {
                Console.WriteLine(userInfo);
            }
            Console.ReadKey();
        }
    }
}

  这里我们可以直接调用BaseDao的GetAll方法,sql会自动在BaseDao中帮我们拼装好,得到的结果如下:

  

  这里我们可以看见的效果是BaseDao帮我们把数据库中表的数据封装到了对象中.不需要我们手动的来进行实例化赋值,希望这个Demo能对初学反射的有点启发,有什么不足之处大家多多指教.

反射入门-浅谈反射用途_根据Ado游标对象创建list集合的更多相关文章

  1. java反射机制浅谈

    一.Java的反射机制浅谈 最近研究java研究得很给力,主要以看博文为学习方式.以下是我对java的反射机制所产生的一些感悟,希望各位童鞋看到失误之处不吝指出.受到各位指教之处,如若让小生好好感动, ...

  2. java的反射机制浅谈(转)

    原文链接:java的反射机制浅谈 一.java的反射机制浅谈 1.何谓反射机制 根据网文,java中的反射机制可以如此定义: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性 ...

  3. 【C#】:浅谈反射机制 【转】

    http://blog.csdn.net/lianjiangwei/article/details/47207875 什么是反射? 反射提供了封装程序集.模块和类型的对象(Type 类型).可以使用反 ...

  4. 【转】Windows SDK入门浅谈

    前言 如果你是一个编程初学者,如果你刚刚结束C语言的课程.你可能会有点失望和怀疑:这就是C语言吗?靠它就能编出软件?无法想象Windows桌面上一个普通的窗口是怎样出现在眼前的.从C语言的上机作业到W ...

  5. c#浅谈反射内存的处理

    这段时间由于公司的项目的要求,我利用c#的反射的机制做了一个客户端框架.客户端里的所有的模块都是以一定形式进行提供,例如:FORM,UserControl. 在做的过程中很简单与愉快.具体的过程如下: ...

  6. 05 入门 - 浅谈 ASP.NET MVC程序的工作原理

    目录索引:<ASP.NET MVC 5 高级编程>学习笔记 本篇内容 1. Global.asax文件 2. RouteConfig.cs文件 3. 视图命名和寻址的规则 前面创建了一个简 ...

  7. ChromeExtension入门浅谈

    0.写在前面的话 朋友上班时每天好几个时段都有个客流信息需要汇报到微信里,都是照着网页上的数据手动填写,着实麻烦.所以给写了个简单的函数每次到控制台里去运行,但是体验也并不好,今天就花了一整天的时间鼓 ...

  8. 编程基础系列--之--浅谈List、Set、Map和泛型(一)——单列集合

    之前在学习Java时对于泛型,集合的理解一直模模糊糊,随着时间的推移,对泛型和集合有了一些浅显的认知,打算写出来巩固一下,也希望各位大佬能指出理解不当之处,万分感谢!!! 在Java语言中,集合分为两 ...

  9. Salesforce Consumer Goods Cloud 浅谈篇四之店内拜访的创建和执行

    本篇参考: https://v.qq.com/x/page/f0772toebhd.html https://v.qq.com/x/page/e0772tsmtek.html https://v.qq ...

随机推荐

  1. svn eclipse链接

    先下载site-1.8.22.zip 安装包 然后 在D:\software\eclipse\dropins 目录下新建 svn文件夹 把下载的文件解压到该文件夹下 ,*.xml 删除 不需要 只要 ...

  2. Win10系统Ping端口及利用telnet命令Ping 端口

    启用 telnet 客户端组件为 Ping 端口做准备 在程序界面下,选择“打开或关闭Windows功能”,如下图所示: 在打开的对话框中,找到“Telnet客户端”并勾选.最后点击“确定”,等待几分 ...

  3. image-set实现Retina屏幕下图片显示详细介绍

    支持image-set:如果你的浏览器支持image-sete,而且是普通显屏下,此时浏览器会选择image-set中的@1x背景图像: Retina屏幕下的image-set:如果你的浏览器支持im ...

  4. scala 模式匹配详解 2 scala里是怎么实现的?

    在这篇martin和另外两位模式匹配领域专家的论文里说了模式匹配的几种实现方式,以及scala是选择哪种方式来实现的.http://lampwww.epfl.ch/~emir/written/Matc ...

  5. C语言程序设计--文件操作

    前言 这里尝试与Python对别的方法来学习C语言的文件操作,毕竟我是Pythoner. 文件打开与关闭 Python #因为是和C语言比对,所以不使用with filename = "/e ...

  6. hosts文件配置不生效的解决办法

    分析可能的原因并给出相应的解决方案. 第一 种情况,在开启浏览器的时候修改磁盘上的hosts文件,比如说加了原先没有的一句"127.0.0.1 www.360.cn",保存host ...

  7. day_5.26python面试重点

    列表生成式: ''' 2018-5-26 19:40:58 生成器(generator):在Python中,这种⼀边循环⼀边计算的机制. ''' # 第一种实现 :只要把⼀个列表⽣成式的[ ]改成( ...

  8. git命令无法自动补全(sles11.3)

    找到git-completion bash文件 find / -name 'git-completion' /usr/share/doc/git-1.7.1/contrib/completion/gi ...

  9. 洛谷P1141 01迷宫【bfs】

    题目链接:https://www.luogu.org/problemnew/show/P1141 题意: 有一个填了0和1的n*n的格子,只能0走到1,1走到0 有m组询问(数据量是1e5),问某一个 ...

  10. [No000014F]计算机编程语言家族史

    https://www.levenez.com/lang/