返回值该是什么?——泛型实践

      对于泛型的初步的了解,请见http://blog.csdn.net/lifen0908/article/details/43450921  。这篇博客主要是说说泛型在机房中的运用。

一、假如是返回值实体:

    我用查询学生基本信息的窗口来说明当我们的返回值是实体的情况:

首先是D层:

<span style="font-family:KaiTi_GB2312;"> Dim sql As String '定义字符串变量sql 用于存放要执行的sql语句
        Dim table As DataTable '定义表变量table 用于存储执行的结果并返回
        Dim paras As SqlParameter() = {New SqlParameter("@cardno", studInfo.cardno)}
        sql = "select * from student_info where cardno = @cardno "
        table = Sqlhelper.SqlHelper.ExecSelect(sql, CommandType.Text, paras)

        Dim studentEntity As New Entity.Studentinfo
        If table.Rows.Count <> 0 Then

            studentEntity.cash = table.Rows(0).Item("cash")
            studentEntity.department = table.Rows(0).Item("department")
            studentEntity.grade = table.Rows(0).Item("grade")
            studentEntity.sex = table.Rows(0).Item("sex")
            studentEntity.studentno = table.Rows(0).Item("studentno")
            studentEntity.txtclass = table.Rows(0).Item("class")
            studentEntity.cash = table.Rows(0).Item("cash")
            studentEntity.studentname = table.Rows(0).Item("studentname")
            studentEntity.department = table.Rows(0).Item("department")
            studentEntity.grade = table.Rows(0).Item("grade")
            studentEntity.sex = table.Rows(0).Item("sex")
            studentEntity.status = table.Rows(0).Item("status")
            studentEntity.ischeck = table.Rows(0).Item("ischeck")
        End If</span>
<span style="font-family:KaiTi_GB2312;">Return studentEntity
</span>
<span style="font-family:KaiTi_GB2312;">  </span>

      大家看到了,假如我们的返回值是实体,在D层,我们首先需要将已经查询到的表赋值给datatable,也就是这里定义成的table,然后将table中的每一个字段赋值给了实体,也就是这里写的studentEntity。

看看U层:

<span style="font-family:KaiTi_GB2312;">Dim strResult2 As Entity.Studentinfo
        strResult2 = ChaStu.QueryCardNO(studInfo)
        If IsNothing(strResult2) Then
            MsgBox("用户不存在")
            txtcardno.Text = ""
            txtcardno.Select()
            txtcardno.Focus()

        Else

            txtstudentno.Text = strResult2.studentno
            txtclass.Text = strResult2.txtclass
            txtcash.Text = strResult2.cash
            txtname.Text = strResult2.studentname
            txtdepartment.Text = strResult2.department
            txtgrade.Text = strResult2.grade
            txtsex.Text = strResult2.sex
            txtstatus.Text = strResult2.status
            txtps.Text = strResult2.ischeck
        End If</span>

      D层查询到的赋值给了实体,然后在U层的时候,将每一个实体又赋值给了窗体上的文本框,于是完成了将D层查询到的内容传到了U层的功能,这就是传实体,返回值也是实体。这样做明显是很麻烦的。

二、假如返回值是datatable

    我们以机房收费系统中基本数据设定的窗体来说明,基本数据设定的第一个步骤就是将数据库中的基本数据设定查询的结果反映到窗体上,我们来看看代码。

D层代码:

<span style="font-family:KaiTi_GB2312;"> Dim sql As String
        Dim table As DataTable
        sql = "select * from BasicData_info"
        table = Sqlhelper.SqlHelper.ExecSelectNo(sql, CommandType.Text)
        Return table</span>
      D层的操作就是增删改查,所以几乎都是重复的代码。

    U层的代码直接就是将表的内容赋值给文本框,在此省略代码。

    比较可以知道,返回Datetable还是比返回实体简单很多的。

三、返回为泛型(mylist)

1、封装公共函数——泛型

    泛型也是一张表,通过一个函数,一个查询的参数,将查询出的结果给了一张表。

    首先,泛型和sqlhelp一样,也是一个公共的函数,需要进行封装,由于在D层的时候需要很频繁的使用它,于是我在D层创建一个类,写下了这个函数。当然了,他的限制就是实体的属性名必须和列名对应。

<span style="font-family:KaiTi_GB2312;">Imports System.Collections.Generic '添加泛型的命名空间
Imports System.Reflection  '添加反射 为了使用propertyinfo

Public Class ConvertHelper
    '将datatable转化为泛型集合
    Public Shared Function convertToList(Of T As {New})(ByVal dt As DataTable) As IList(Of T)
        '注意:convertToList(Of T As {New}) 这里的new是用来约束T的,必须有,不然new T的时候会出现错误
        Dim myList As New List(Of T) '定义最终返回的集合
        Dim myTpye As Type = GetType(T) '得到实体类的类型名
        Dim dr As DataRow  '定义行集
        Dim tempName As String = String.Empty '定义一个临时变量

        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
                tempName = pr.Name
                If (dt.Columns.Contains(tempName)) Then
                    If (pr.CanWrite = False) Then
                        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
</span>

     已经封装好的泛型已经写好啦,接下来看看如何使用它

2、使用公共函数——泛型

(1)窗体

        将查询到的一张表全部用来显示在控件中,这里我们以收取金额查询为例。

                  

 (2)实体代码

     首先,由于这里需要的是一个开始日期,一个结束日期,所以在实体层的时候,我比数据库中的字段多添加了俩个实体,也就是下面的这俩个,其他的实体就不在这里列出啦。

<span style="font-family:KaiTi_GB2312;">  Public Property redate1 As String
        Get
            Return _date1
        End Get
        Set(value As String)
            _date1 = value
        End Set
    End Property
    Public Property redate2 As String
        Get
            Return _date2
        End Get
        Set(value As String)
            _date2 = value
        End Set
    End Property</span>


(3)接口代码

     然后就是接口层啦,其实写法也不难,但是第一次用的时候还是出错了很多。

<span style="font-family:KaiTi_GB2312;"> Function Ichargequ(ByVal LDate As Entity.Rechargeinfo) As List(Of Entity.Rechargeinfo)</span>

(4)D层代码

<span style="font-family:KaiTi_GB2312;">Imports IDAL
Imports Entity
Imports System.Data.SqlClient
Imports Sqlhelper.SqlHelper
Public Class SqlServerRechargeinfoDAL : Implements Irechargeinfo


    Public Function Ichargequ(LDate As Rechargeinfo) As List(Of Rechargeinfo) Implements Irechargeinfo.Ichargequ

        Dim sql As String '定义字符串变量sql 用于存放要执行的sql语句
        Dim table As DataTable '定义表变量table 用于存储执行的结果并返回
        Dim mylist As List(Of Entity.Rechargeinfo)

        sql = "select * from recharge_info where redate >= @redate1  and redate<= @redate2"
        Dim paras As SqlParameter() = {New SqlParameter("@redate1", LDate.redate1),
                                       New SqlParameter("@redate2", LDate.redate2)}
        table = Sqlhelper.SqlHelper.ExecSelect(sql, CommandType.Text, paras)

        If table.Rows.Count > 0 Then
            mylist = ConvertHelper.convertToList(Of Entity.Rechargeinfo)(table)
            Return mylist
        Else
            Return Nothing

        End If
    End Function</span>

(5)U层代码

     工厂层和B层的代码在此不写啦,我们看一下U层的代码:

<span style="font-family:KaiTi_GB2312;"> Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim date1 As Date
        Dim date2 As Date
        date1 = DateTimePicker1.Value
        date2 = DateTimePicker2.Value

        If DateDiff("n", CDate(date1), CDate(date2)) < 0 Then
            MsgBox("日期冲突,请重新修改", vbOKOnly + vbExclamation, "修改日期")
            Exit Sub
            DateTimePicker1.Focus()
        End If

        Dim EDate As New Entity.Rechargeinfo
        Dim BDate As New BLL.ChargeQuBLL
        Dim LDater As New List(Of Entity.Rechargeinfo)

        EDate.redate1 = date1
        EDate.redate2 = date2

        LDater = BDate.ChargeQu(EDate)

        If IsNothing(LDater) = False Then
            DataGridView1.DataSource = LDater

            DataGridView1.Columns.Remove("redate1")
            DataGridView1.Columns.Remove("redate2")
        Else
            date1 = ""

            date2 = ""
        End If
    End Sub</span>

      由于用了DataGridView控件,在实体层的所有字段都会成为他的列名datagridview.columns.remove("redate1")把他移除。

      就这样,将查询到的数据全部都显示在了控件DataGridView上啦。也就是那句很重要的 datagridview.DataSource=LDater.

(6)查询的部分显示

      但是,假如我们不要显示全部的内容,仅仅需要他的一个数据,该怎么办啊?语法是很简单的,这里列举将泛型的值赋给文本框,如下:       txttype.Text = mylist(0).type        txtname.Text = mylist(0).studentname


四、感悟

      什么都是先难后易,整整的掌握了它,变成了自己东西,融入了自己的理解,也就不太那样难啦。

      重构,加油~~~~~~~~~~奋斗奋斗奋斗奋斗



       

评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值