请参阅以下代码:
Public Function ExecuteDynamicQuery(ByVal strSQL As String, ByVal list As List(Of clsType), ByVal tyType As clsType) As List(Of clsType) Implements IGenie.ExecuteDynamicQuery
Dim objParameterValues As New clsParameterValues
Dim iConnectionBLL As iConnectionBLL
Dim objCon As DbConnection
Dim objDR As DbDataReader
Dim paramValues() As DbParameter
objParameterValues = New clsParameterValues
iConnectionBLL = New clsConnectionBLL()
objCon = iConnectionBLL.getDatabaseTypeByDescription("Genie2")
Using objCon
paramValues = objParameterValues.getParameterValues
objDR = clsDatabaseHelper.ExecuteReader(objCon, CommandType.Text, strSQL, paramValues)
Do While objDR.Read
Dim tyType2 As clsType = tyType
tyType.PopulateDataReader(objDR)
list.Add(tyType2)
Loop
objDR.Close()
Return list
End Using
End Function
将SQL语句与clsType(基本类型)一起传递给函数。返回类型列表,例如人员名单。例如,在这种情况下,strSQL =“SELECT * FROM Persons”。返回500人的列表,但他们都是同一个人(最后一个人被添加到列表中)。我意识到这是因为列表为每个条目引用了相同的对象。我该如何改变?
答案 0 :(得分:2)
这种情况下,使方法通用会很有用。例如:
Public Function MyGenericMethod(Of T As New)() As List(Of T)
Dim results As New List(Of T)()
For i As Integer = 0 To 9
Dim item As New T()
' Populate item ...
results.Add(item)
Next
Return results
End Function
但是,对于它的价值,我看到人们经常尝试做这种事情,而且我从不和我好好相处。我总是第一个建议公共代码应该被封装而不是重复的地方,但是,我从来没有被说服创建某种类型的数据访问层来封装对ADO的调用,但< em>不也封装SQL,是个好主意。
考虑一下ADO,它本身就是数据访问层那部分的封装。当然,它可能比执行一个简单的SQL命令要多几行代码,但这种额外的复杂性是有原因的。为了支持数据源的所有功能,这是必要的。如果您尝试简化它,不可避免地,您将来有一天需要使用数据源的其他功能,但您的简化界面将不支持它。在我看来,每个数据访问方法应该直接使用所有必需的ADO对象,而不是尝试创建一些常用方法来实现。是的,这确实意味着你的许多数据访问方法在结构上会非常相似,但我认为从长远来看你会更快乐。
答案 1 :(得分:1)
我减少了原始代码。以下示例在功能上等同于您发布的内容。如果不了解更多关于你的类型的内容,很难给你提供更多的东西,但是减少代码可能会使代码足够清晰,你可以找到解决方案:
Public Function ExecuteDynamicQuery(ByVal sql As String, ByVal list As List(Of clsType), ByVal type As clsType) As List(Of clsType) Implements IGenie.ExecuteDynamicQuery
Dim paramValues() As DbParameter = New clsParameterValues().getParameterValues()
Using conn As DbConnection = iConnectionBLL.getDatabaseTypeByDescription("Genie2"), _
rdr As DbDataReader = clsDatabaseHelper.ExecuteReader(conn, CommandType.Text, sql, paramValues)
While rdr.Read()
type.PopulateDataReader(rdr)
list.Add(type)
End While
Return list
End Using
End Function
我可以给你一些额外的建议:
ExecuteReader()
方法支持此方法,但您只传递一个空数组。解决此问题,或将遭到入侵。New clsType
(并且看起来你可能有Option Strict Off,这样可能会在运行时爆炸),通过一些凌乱的反射代码,切换到使用#2中建议的泛型,或接受可以为您构建新对象的Func(Of clsType)
委托。