机房重构——DataTable转泛型

机房重构前期一直是用的DataTable来返回数据库中的值,当时没有感觉很麻烦,后来接触了泛型,才发现DataTable还是比较麻烦的。


DataTable:

不允许透明检索数据,应用程序和数据库是强耦合,对数据库结构的任何改变你都需要你的程序有所改动,这样就造成了代码和数据库耦合性更强。在你写U层代码的时候需要知道数据库字段的顺序。例如

Dim table As DataTable
        table = facade.CheckData()

        '使用泛型,就必须知道数据库的结构
        txtRate.Text = table.Rows(0).Item(0)
        txtTmpRate.Text = table.Rows(0).Item(1)
        txtUnitTime.Text = table.Rows(0).Item(2)
        txtLeastTime.Text = table.Rows(0).Item(3)
        txtPrepareTime.Text = table.Rows(0).Item(4)
        txtLimitCash.Text = table.Rows(0).Item(5)


泛型:

泛型的作用是避免强制类型转换,提高类型安全,提高代码的重用性,减少装箱 拆箱提高性能,减少错误。


DataTable转泛型:

DataTable偏向于面向过程,使用时需要知道数据库中它的位置;List偏向于面向对象,只需要点出它的字段名即可,不需要知道数据库里面的结构。

下面用一张图来表示一下:


实体类是数据库的映射,实体类的属性和数据库表中的字段相对应。

把DataTable中每一行记录作为一个实体类,把其中的字段读取出来存放在实体类的属性中,再把所用实体类存放在泛型集合中。

优点:

   •无需知道数据库的结构

   •符合面象对象的思想

注意事项:

   •实体类的属性必须和数据库表中字段名一模一样

实例:

就拿基本数据设定来说吧

1.建立转换泛型的模块/类

我是建立在了D层

Imports System.Reflection
Public Class ConvertHelper
    '将datatable转化为泛型集合
    Public Shared Function ConvertToList(Of Turn As {New})(ByVal dt As DataTable) As IList(Of Turn)
        '这里new是用来约束T的

        Dim myList As New List(Of Turn) '定义最终返回的集合
        Dim myType As Type = GetType(Turn) '得到实体类的类型名
        Dim dr As DataRow  '定义行集
        Dim tempName As String = String.Empty  '定义一个临时变量

        '遍历该对象的所有 数据行
        For Each dr In dt.Rows
            Dim myTurn As New Turn
            Dim propertys() As PropertyInfo = myTurn.GetType().GetProperties()  '定义属性集合
            Dim pr As PropertyInfo
            '遍历该对象的所有 属性
            For Each pr In propertys
                tempName = pr.Name '将属性名赋值给临时变量
                If (dt.Columns.Contains(tempName)) Then '将此属性与DataTable里的列名比较,查看DataTable里面是否包含此属性
                    '判断此属性是否有Setter
                    If (pr.CanWrite = False) Then
                        Continue For '跳出,继续执行for循环
                    End If
                    Dim value As Object = dr(tempName) '定义一个对象型的变量来保存列的值
                    If (value.ToString <> DBNull.Value.ToString) Then  '如果为非空,则赋值给对象的属性
                        pr.SetValue(myTurn, value, Nothing) '在运行期间,通过反射,动态的访问一个对象的属性

                    End If
                End If
            Next
            myList.Add(myTurn) '添加到集合
        Next
        Return myList  '返回实体集合

    End Function
End Class
2.使用泛型

Imports System.Data.SqlClient
Public Class DataDAL : Implements IDAL.IBasicData

    Public Function CheckData() As List(Of Entity.BasicDataInfo) Implements IDAL.IBasicData.CheckData

        Dim sqlHelper As New SqlHelper.SqlHelper
        Dim sql As String
        Dim table As New DataTable
        Dim mylist As New List(Of Entity.BasicDataInfo)

        sql = "Select * from BasicData_Info "
        table = sqlHelper.ExecSelectNo(sql, CommandType.Text)
        mylist = ConvertHelper.ConvertToList(Of Entity.BasicDataInfo)(table)
        Return mylist
    End Function
End Class
3.泛型数据的获取

Dim mylist As New List(Of Entity.BasicDataInfo)
        mylist = facade.CheckData()

        txtRate.Text = mylist(0).Rate
        txtTmpRate.Text = mylist(0).tmpRate
        txtUnitTime.Text = mylist(0).unitTime
        txtLeastTime.Text = mylist(0).leastTime
        txtPrepareTime.Text = mylist(0).prepareTime
        txtLimitCash.Text = mylist(0).limitCash

直接就可以点出它的字段,不需知道数据库结构


问题:

 

类型“System.String”的对象无法转换为类型“System.Char”



以为数据库里设置的是Char类型,里面没有string类型,在实体层里面设置的也是Char类型,将其改为string类型即可


总结:

实践是检验真理的唯一标准,这次真正实践过,才知道泛型比DataTable好用很多。




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
要将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 ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值