这是许多程序员试图创建“数据库层”的地方,其方法签名的变化看起来像这样:
Public DataSet ExecuteSQL(ByVal sql As String) As DataSet
这样可以将所有的样板连接代码隔离在一个地方。输入一个sql命令字符串,输出数据。很容易。
不要这样做!
这个方法走的方向是正确的,但有一个非常大的缺陷:它强制你使用字符串操作将参数值替换到sql查询中。这会导致可怕的sql注入安全漏洞。
相反,确保在您的方法中包含一些机制来单独提示sql参数。这通常以函数的附加参数形式出现,可以简单地作为KeyValuePairs数组。如果您熟悉lambda表达式,我的首选模式看起来像这样:
Public Iterator Function GetData(Of T)(ByVal sql As String, ByVal addParameters As Action(Of SqlParameterCollection), ByVal translate As Func(Of IDatarecord, T)) As IEnumerable(Of T)
Using cn As New SqlConnection("connection string"), _
cmd As New SqlCommand(sql, cn)
addParameters(cmd.Parameters)
cn.Open()
Using rdr As SqlDataReader = cmd.ExecuteReader()
While rdr.Read()
Yield(translate(rdr))
End While
End Using
End Using
End Function
要调用该函数,您需要执行以下操作:
Dim bigCustomers = GetData("SELECT * FROM Customers WHERE SalesTotal > @MinSalesTotal", _
Sub(p) p.Add("@MinSalesTotal", SqlDbType.Decimal, 1000000), _
MyCustomerClass.FromIDataRecord)