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

时间:2020-12-26 19:43:52

      对于泛型的初步的了解,请见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


四、感悟

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

      重构,加油~~~~~~~~~~返回值该是什么?——泛型实践返回值该是什么?——泛型实践返回值该是什么?——泛型实践返回值该是什么?——泛型实践