DataTable数据转换为实体


 我们在用三层架构编写软件时,经常会遇到如下问题,就是三层之间的参数传递问题:如果我们在D层查询出数据是DataTable类型的,那么我们在B层甚至U层使用这条数据时,就要用DataTable类型来回传递了,无论什么情况,我们都会不可避免的要填写读取的字段。例如我们需要使用第一条记录的的某个字段,代码需要这样写:mrc.count(*)rows(*).这样写的坏处有很多:

        1、容易写错,并且编译器是检查不出来的;

        2、我们需要详细的了解数据库的结构;

        3、 不符合面向对象编程思想。

       这个问题研究了很长时间,查找了无数的资料,终于找到解决方法了。将DataTable数据转化成单个的实体类,然后将这些实体类放到泛型集合中。结果图如下:

 

       实体类是数据库的映射,每一条记录对应一个实体,实体的属性对应每一条记录的字段,并且是一一对应的。我们这里是把查询到的每一条数据都作为一个实体提取出来,然后将这些实体存放到泛型集合中。这样我们在使用数据的时候只要知道属性就可以,使用代码如下:List.(items).property。这样,是不是简化了代码,减少了工作量,也减少了错误率。

       那么,是如何用代码实现的呢?首先是实体类,这里,我们假设数据库中只有两个字段用户民和密码:

  1. Public Class User  
  2.     Public UserName As String  
  3.     Public PassWord As String  
  4.     Public Property _username() As String  
  5.             Get  
  6.                 Return UserName  
  7.             End Get  
  8.             Set(value As String)  
  9.                 UserName = value  
  10.             End Set  
  11.         End Property  
  12.         Public Property _password() As String  
  13.             Get  
  14.                 Return PassWord  
  15.             End Get  
  16.             Set(value As String)  
  17.                 PassWord = value  
  18.             End Set  
  19.         End Property  
  20. End Class  
Public Class User
	Public UserName As String
	Public PassWord As String
	Public Property _username() As String
	        Get
	            Return UserName
	        End Get
	        Set(value As String)
	            UserName = value
	        End Set
	    End Property
	    Public Property _password() As String
	        Get
	            Return PassWord
	        End Get
	        Set(value As String)
	            PassWord = value
	        End Set
	    End Property
End Class
        这里,我是用了一个ModelHelper类来实现这个功能,因为这是关于参数的类,将这个类放到了Model层。代码如下:
  1. Imports System.Collections.Generic    '命名空间  
  2. Imports System.Reflection            '引入反射:便于使用propertyInfo  
  3. ''' <summary>  
  4. ''' 实体转换类,此类用于将数据表格转换为实体集合  
  5. ''' </summary>  
  6. ''' <remarks></remarks>  
  7. Public Class ModeHelper  
  8.     Public Function convertToList(Of T As {New})(ByVal dt As DataTable) As IList(Of T)  
  9.         '将dataTable转化为泛型集合  
  10.         '1convertToList(Of T As {New})这里的new是用来约束参数T的,否则实例化时回出现错误  
  11.         '2List后边的参数总是(of +)类型  
  12.         Dim myList As New List(Of T)   '定义返回值集合  
  13.         Dim myType As Type = GetType(T)   '定义实体类类型名  
  14.         Dim dr As DataRow           '定义行集  
  15.   
  16.         Dim tempName As String = String.Empty    '定义一个临时变量,用来存放  
  17.         '数据表总是一个二维表格,需要使用数组:dr和pr,dt表示sqlhelper返回结果  
  18.         For Each dr In dt.Rows      '遍历DataTable所有记录  
  19.             Dim myT As New T       '定义一个实体对象  
  20.             Dim Propertys() As PropertyInfo = myT.GetType().GetProperties()   '定义属性集合,获得公共属性  
  21.             Dim pr As PropertyInfo  
  22.             For Each pr In Propertys    '遍历DataTable所有字段  
  23.                 tempName = pr.Name     '将属性名赋值给临时变量  
  24.                 '检查Datatable是否包含此列(列名==对象属性名)  
  25.                 If (dt.Columns.Contains(tempName)) Then   '将此属性与datatable的列名比较,查看datatable是否包含此列  
  26.                     If (pr.CanWrite = FalseThen          '判断此属性是否有Setter  
  27.                         Continue For        '继续执行  
  28.                     End If  
  29.                     Dim value As Object = dr(tempName)     '定义一个对象性的变量来保存列的值  
  30.                     If (value.ToString <> DBNull.Value.ToString()) Then    '如果非空,则付给对象的属性  
  31.                         pr.SetValue(myT, value, Nothing)          '运行期间,通过反射,动态的访问一个对象的属性  
  32.                     End If  
  33.                 End If  
  34.             Next  
  35.             myList.Add(myT)      '添加到集合  
  36.         Next  
  37.         Return myList    '返回结果  
  38.     End Function  
  39. End Class  
Imports System.Collections.Generic    '命名空间
Imports System.Reflection            '引入反射:便于使用propertyInfo
''' <summary>
''' 实体转换类,此类用于将数据表格转换为实体集合
''' </summary>
''' <remarks></remarks>
Public Class ModeHelper
    Public Function convertToList(Of T As {New})(ByVal dt As DataTable) As IList(Of T)
        '将dataTable转化为泛型集合
        '1convertToList(Of T As {New})这里的new是用来约束参数T的,否则实例化时回出现错误
        '2List后边的参数总是(of +)类型
        Dim myList As New List(Of T)   '定义返回值集合
        Dim myType As Type = GetType(T)   '定义实体类类型名
        Dim dr As DataRow           '定义行集

        Dim tempName As String = String.Empty    '定义一个临时变量,用来存放
        '数据表总是一个二维表格,需要使用数组:dr和pr,dt表示sqlhelper返回结果
        For Each dr In dt.Rows      '遍历DataTable所有记录
            Dim myT As New T       '定义一个实体对象
            Dim Propertys() As PropertyInfo = myT.GetType().GetProperties()   '定义属性集合,获得公共属性
            Dim pr As PropertyInfo
            For Each pr In Propertys    '遍历DataTable所有字段
                tempName = pr.Name     '将属性名赋值给临时变量
                '检查Datatable是否包含此列(列名==对象属性名)
                If (dt.Columns.Contains(tempName)) Then   '将此属性与datatable的列名比较,查看datatable是否包含此列
                    If (pr.CanWrite = False) Then          '判断此属性是否有Setter
                        Continue For        '继续执行
                    End If
                    Dim value As Object = dr(tempName)     '定义一个对象性的变量来保存列的值
                    If (value.ToString <> DBNull.Value.ToString()) Then    '如果非空,则付给对象的属性
                        pr.SetValue(myT, value, Nothing)          '运行期间,通过反射,动态的访问一个对象的属性
                    End If
                End If
            Next
            myList.Add(myT)      '添加到集合
        Next
        Return myList    '返回结果
    End Function
End Class
        下边是D层的调用代码:
  1. Public Function SelectUsers1(user ) As List(Of Charge.Model.User)  
  2.     Dim mrc as dataTable         '假设mrc是从数据库中查询出来的DataTable数据表  
  3.     Dim myList As List(Of Charge.Model.User)     '定义一个集合用来返回转化后的实体集合  
  4.     Dim mHelper As New Charge.Model.ModeHelper   '实例化一个实体转换类  
  5.     myList = mHelper.convertToList(Of Charge.Model.User)(mrc)    '调用实体转换类的方法,转换数据  
  6.     Return myList    '返回结果  
  7. End Function  
Public Function SelectUsers1(user ) As List(Of Charge.Model.User)
	Dim mrc as dataTable         '假设mrc是从数据库中查询出来的DataTable数据表
	Dim myList As List(Of Charge.Model.User)     '定义一个集合用来返回转化后的实体集合
	Dim mHelper As New Charge.Model.ModeHelper   '实例化一个实体转换类
	myList = mHelper.convertToList(Of Charge.Model.User)(mrc)    '调用实体转换类的方法,转换数据
	Return myList    '返回结果
End Function
                 在这里,我们只讨论将DataTable数据类型转换问题,其他问题不讨论,一切以假设作为前提,参考代码需谨慎。
      到目前为止,这些代码解决了我遇到的问题,但是仔细思考一下,这里一个实体对应数据库的一条记录,也就是说,每一个表都会有一个实体类或者泛型集合来对应,但是如果是多个表联合查询,该如何解决呢?目前我还没有解决这个问题,留待以后解决。



出处:http://blog.csdn.net/u010942465/article/details/38024021





在 C# DataTable 转换实体有多种方案,下面介绍其比较常用的两种。 1. 使用反射实现 这种方法是通过使用反射获取 DataTable 的列名和对应的值,然后通过反射将值赋给实体对象的属性。代码如下: ```csharp public static List<T> DataTableToList<T>(DataTable dt) where T : new() { List<T> list = new List<T>(); foreach (DataRow dr in dt.Rows) { T t = new T(); PropertyInfo[] propInfos = t.GetType().GetProperties(); foreach (PropertyInfo propInfo in propInfos) { if (dt.Columns.Contains(propInfo.Name)) { object value = dr[propInfo.Name]; if (value != DBNull.Value) { propInfo.SetValue(t, value, null); } } } list.Add(t); } return list; } ``` 使用示例: ```csharp DataTable dt = GetDataTable(); List<MyEntity> list = DataTableToList<MyEntity>(dt); ``` 2. 使用泛型类库实现 这种方法是通过使用泛型类库来实现 DataTable 转换实体,例如使用 Dapper 类库。Dapper 是一个轻量级的 ORM 类库,可以方便地将数据数据库读取到实体对象。使用 Dapper 类库将 DataTable 转换实体的代码如下: ```csharp public static List<T> DataTableToList<T>(DataTable dt) where T : new() { List<T> list = new List<T>(); using (var conn = new SqlConnection(connectionString)) { conn.Open(); list = conn.Query<T>("select * from @dt", new { dt = dt }).ToList(); } return list; } ``` 使用示例: ```csharp DataTable dt = GetDataTable(); List<MyEntity> list = DataTableToList<MyEntity>(dt); ``` 注意:使用 Dapper 类库需要先安装 NuGet 包,在控制台执行以下命令即可: ```bash Install-Package Dapper ```
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值