DataTable数据转换为实体
2015-07-13 20:24
197 查看
我们在用三层架构编写软件时,经常会遇到如下问题,就是三层之间的参数传递问题:如果我们在D层查询出数据是DataTable类型的,那么我们在B层甚至U层使用这条数据时,就要用DataTable类型来回传递了,无论什么情况,我们都会不可避免的要填写读取的字段。例如我们需要使用第一条记录的的某个字段,代码需要这样写:mrc.count(*)rows(*).这样写的坏处有很多:
1、容易写错,并且编译器是检查不出来的;
2、我们需要详细的了解数据库的结构;
3、 不符合面向对象编程思想。
这个问题研究了很长时间,查找了无数的资料,终于找到解决方法了。将DataTable数据转化成单个的实体类,然后将这些实体类放到泛型集合中。结果图如下:
实体类是数据库的映射,每一条记录对应一个实体,实体的属性对应每一条记录的字段,并且是一一对应的。我们这里是把查询到的每一条数据都作为一个实体提取出来,然后将这些实体存放到泛型集合中。这样我们在使用数据的时候只要知道属性就可以,使用代码如下:List.(items).property。这样,是不是简化了代码,减少了工作量,也减少了错误率。
那么,是如何用代码实现的呢?首先是实体类,这里,我们假设数据库中只有两个字段用户民和密码:
[vb]
view plaincopyprint?
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
[vb]
view plaincopyprint?
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
[vb]
view plaincopyprint?
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
到目前为止,这些代码解决了我遇到的问题,但是仔细思考一下,这里一个实体对应数据库的一条记录,也就是说,每一个表都会有一个实体类或者泛型集合来对应,但是如果是多个表联合查询,该如何解决呢?目前我还没有解决这个问题,留待以后解决。
出处:/article/2530191.html
我们在用三层架构编写软件时,经常会遇到如下问题,就是三层之间的参数传递问题:如果我们在D层查询出数据是DataTable类型的,那么我们在B层甚至U层使用这条数据时,就要用DataTable类型来回传递了,无论什么情况,我们都会不可避免的要填写读取的字段。例如我们需要使用第一条记录的的某个字段,代码需要这样写:mrc.count(*)rows(*).这样写的坏处有很多:
1、容易写错,并且编译器是检查不出来的;
2、我们需要详细的了解数据库的结构;
3、 不符合面向对象编程思想。
这个问题研究了很长时间,查找了无数的资料,终于找到解决方法了。将DataTable数据转化成单个的实体类,然后将这些实体类放到泛型集合中。结果图如下:
实体类是数据库的映射,每一条记录对应一个实体,实体的属性对应每一条记录的字段,并且是一一对应的。我们这里是把查询到的每一条数据都作为一个实体提取出来,然后将这些实体存放到泛型集合中。这样我们在使用数据的时候只要知道属性就可以,使用代码如下:List.(items).property。这样,是不是简化了代码,减少了工作量,也减少了错误率。
那么,是如何用代码实现的呢?首先是实体类,这里,我们假设数据库中只有两个字段用户民和密码:
[vb]
view plaincopyprint?
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
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层。代码如下:
[vb]
view plaincopyprint?
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
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层的调用代码:
[vb]
view plaincopyprint?
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
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数据类型转换问题,其他问题不讨论,一切以假设作为前提,参考代码需谨慎。
到目前为止,这些代码解决了我遇到的问题,但是仔细思考一下,这里一个实体对应数据库的一条记录,也就是说,每一个表都会有一个实体类或者泛型集合来对应,但是如果是多个表联合查询,该如何解决呢?目前我还没有解决这个问题,留待以后解决。
出处:/article/2530191.html
相关文章推荐
- 介绍Google App Engine
- leetcode 027 —— Remove Element
- Node:普通归并
- 英格兰、威尔士、北爱尔兰教育体系
- 使用const关键字进行函数重载
- POJ 2886 Who Gets the Most Candies?(线段树·约瑟夫环)
- 第一篇博客
- POJ 2481 Cows
- Gym 100496A Avangard Latin Squares(矩阵游戏)
- JSP 标准标签库(JSTL)之最常用的JSTL标签总结
- const型变量与函数重载
- CXF WebService整合Spring
- 算法导论 第五章:随机算法
- 类的const和非const成员函数的重载
- hdu 4908 BestCoder Sequence 发现M中值是字符串数, 需要预处理
- C++ 学习之函数重载、基于const的重载
- javaWeb
- 跟着实例学习设计模式(8)-适配器模式adapter(结构型)
- Linux下使用Caffe对图片进行训练并分类的简单流程
- [C++] const与重载