机房重构——DataTable转泛型

                                      DataTable转泛型

      前言:在机房基本已经做完的时候,突然发现一个很严重的问题,那就是别人都转泛型了,我怎么没有转呢?当时一下就有点无语了,我做了这么长时间的机房,好不容易要做完了,怎么把这么大的事给忘了呢,看来这回又得继续了。曾经某个同学告诉我说转泛型一点都不难,可简单了,可是昨天写的时候我发现,也没有我想象中的那么简单,虽然说是用一个类就能解决的问题,但我是用c#写的,参考着VB.NET 版的写,也费了了我好大劲呢,但也从中学到不少东西。

 什么是泛型:

        泛型是程序设计语言的一种特性。允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明。各种程序设计语言和其编译器、运行环境对泛型的支持均不一样。将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型。泛型类是引用类型,是堆对象,主要是引入了类型参数这个概念。在程序编码中一些包含类型参数的类型,也就是说泛型的参数只可以代表类,不能代表个别对象。(这是当今较常见的定义)。

使用泛型的好处:

  1.泛型是一种强类型。其处理速度要比普通类快。
  2.泛型用来解决创建和使用新的数据类型。泛型也使不同场合的代码重用更加方便。
  3.与传统的类相比,泛型更加高效。泛型模板可以提供传统类不能实现的代码重用,在某些情况下可以少些很多代码。
  4.与传统类只能使用通用类型(如object)不同,泛型可以指定使用的类型,提供更好的类型保护。
  5.性能和类型安全性大大提高。

  6. 使用泛型类型可以最大限度地重用代码、保护类型的安全以及提高性能。

代码:

用学生上机记录查询来做例子:

因为在以后会有很多地方用到dataTable转泛型,所以把这个过程写成一个单独的类比较合适,可以写在U层,也可以写在D层。在这里我是写到了D层。

首先是添加两个引用:

using System.Reflection;    //一下是添加的引用
using System.Data ;
方法代码:

namespace LoginDAL
{
    public class converttoListDAO
    {
        /// <summary>
        /// 单表查询结果转换成泛型集合
        /// </summary>
        ///<param name="T">泛型集合类型</param>
        /// <typaram name="dt">查询结果DataTable</param>
        /// <returns>以 实体类为元素的泛型集合</returns>
        public static List<T> DatatoList<T>(DataTable dt) where T:new ()
        {
            //定义集合
            List<T> mylist = new List<T>();
            //获得此模型的类型
            Type type=typeof (T);
            //定义一个临时变量
            string tempName = string.Empty;
            //遍历DataTable 中所有的数据行
            foreach ( DataRow dr in dt.Rows )
            {
                T t = new T();
                //获得此模型的公共属性
                PropertyInfo[] pro = t.GetType().GetProperties ();
                //遍历该对象的所有属性
                foreach (PropertyInfo pr in pro)
                {
                    tempName = pr.Name;//将属性名称赋值给临时变量
                    //检查datatable是否包含此列(列名==对象的属性名)
                    if (dt.Columns .Contains (tempName))
                    {
                        //判断此属性是否有setter
                        if (!pr.CanWrite) continue;  //该属性不可写,直接跳出
                        //q取值:
                        object value =(dr[tempName.Trim()]);
                        //int a = Convert.ToInt32(value);
                        //如果非空,则赋给对象的属性
                        if(value !=DBNull .Value )
                        {
                            pr.SetValue(t,value ,null);
                        }
                    }                   
                    
                }
                //对象添加到泛型集合中
                mylist.Add(t);
            }
            return mylist;
        }
    }
}
  Facade层代码:

 public List<Login.Modle.LineInfo > FaceLine(Login.Modle.LineInfo lineinfo)
        {
            //Login.BLL.LineBLL linebll = new Login.BLL.LineBLL();
           //  DataTable lineback1 = new DataTable();

            Login.BLL.LineBLL linebll = new Login.BLL.LineBLL();
            List<Login.Modle.LineInfo > lineback = new List<Login.Modle.LineInfo >();
            lineback = linebll.Linebll (lineinfo);     //数据传入到B层中
            return lineback;
        }
B层代码:

 public List<Login.Modle .LineInfo> Linebll(Login.Modle .LineInfo lineinfo)
        {
            LoginFactory.loginFactory linefactory = new LoginFactory.loginFactory();  //实例化工厂
            Login.IDAL.LineIDAL Iline = linefactory.SelectLine();   //实例化接口
           // DataTable lineback2 = new DataTable();
            List<Login.Modle.LineInfo> lineback2 = new List<Modle.LineInfo>();
            lineback2 = Iline.GetLine (lineinfo);

            return lineback2;

        }
D层代码:

 public class lineDAO:Login.IDAL .LineIDAL 
    {
        //public DataTable GetLine(Login.Modle .LineInfo lineinfo)
        public List<Login.Modle.LineInfo> GetLine(Login.Modle.LineInfo lineinfo)
        {
            SqlParameter[] sqlparams={new SqlParameter ("@cardno",lineinfo .CardNo )};
            string sql2 = "select * from Line_info where Cardno=@cardno ";
            List<Login.Modle.LineInfo> list = new List<Login.Modle.LineInfo>();
            DataTable table2 = new DataTable();
             table2 = SqlHelper.SqlHelper.GetDataTable(sql2, CommandType.Text ,sqlparams);  //调用sqlhelper层
             
            if (table2 .Rows .Count >0)
            {              
                list = LoginDAL.converttoListDAO.DatatoList<Login.Modle.LineInfo>(table2);
            }
	
            return list ;
        }
    }
      虽然在写的时候费了很大的劲,但是也从这过程中学到了不少的东西。在转泛型的时候常出的一个错误就是,类型的转换问题, 原因是我们封装的实体中的属性的类型和数据库中相应字段的类型不同。当我们用泛型集合来代替DataTable的时候我们必须保证我们封装的实体的属性名和数据库中字段名一模一样,也就是说我们必须明确要转换的实体类的类型,否则会报错,另外我们在封装实体的属性的类型必须和我们数据库中相应字段的属性一样。

   当我们遇到新的不会的知识的时候,不要回避,要大胆尝试着接受,只有这样我们才能学到更多的知识。
  







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 32
    评论
要将DataTable换为List,可以使用以下方法之一: 方法一:使用LINQ查询 可以使用LINQ查询将DataTable换为List。首先,使用DataTable的AsEnumerable方法将DataTable换为可枚举的行集合,然后使用LINQ的Select方法将每一行换为目标类型的对象,并将这些对象添加到List中。 ```csharp List<MyClass> list = table.AsEnumerable().Select(row => { MyClass obj = new MyClass(); obj.Field1 = row.Field<type>("ColumnName1"); obj.Field2 = row.Field<type>("ColumnName2"); obj.Field3 = row.Field<type>("ColumnName3"); return obj; }).ToList(); ``` 方法二:使用泛型方法和反射 可以创建一个泛型方法,该方法可以将DataTable换为List。该方法使用反射来动态设置对象的属性值。 ```csharp public static List<T> ConvertDataTableToList<T>(DataTable table) where T : class, new() { List<T> list = new List<T>(); foreach (DataRow row in table.Rows) { T obj = new T(); foreach (PropertyInfo info in obj.GetType().GetProperties()) { if (table.Columns.Contains(info.Name)) { if (row\[info.Name\] != DBNull.Value) { info.SetValue(obj, row\[info.Name\], null); } } } list.Add(obj); } return list; } ``` 使用以上方法之一,您可以将DataTable换为List。请根据您的需求选择适合的方法。 #### 引用[.reference_title] - *1* *2* *3* [C#中将DataTable化成ListT的方法解析](https://blog.csdn.net/naer_chongya/article/details/130422703)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值