SqlConnection.Open()建立连接每个查询?

时间:2014-04-28 17:40:21

标签: sql sql-server vb.net winforms

在我使用远程数据库的Winforms应用程序中,我有以下功能。 (我还有两个类似的函数:一个用于标量查询,失败时返回零,另一个用于更新和插入,失败时返回false。)

目前,所有数据操作都是通过这三个功能进行的。

它工作正常,但总体而言请告知我是否最好在启动我的应用程序时建立连接,然后在应用程序被杀时关闭它?还是在另一个时间? (同样,它是一个Windows窗体应用程序,因此当用户长时间午休时,它有可能停滞不前。)

到目前为止,我没有看到任何不良影响,因为一切似乎都发生了#34;眨眼间......#但我得到的数据更慢,还是有其他潜力内存泄漏等危险?无论函数如何终止,请注意我正在关闭连接。

Public Function GetData(ByVal Query As String) As DataTable
    Dim Con As New SqlConnection(GlobalConnectionString)
    Dim da As New SqlDataAdapter
    Dim dt As New DataTable
    Try
        Con.Open()
        da = New SqlDataAdapter(Query, Con)
        Con.Close()
        da.Fill(dt)
    Catch ex As Exception
        Debug.Print(Query)
        MsgBox("UNABLE TO RETRIEVE DATA" & vbCrLf & vbCrLf & ex.Message, MsgBoxStyle.Critical, "Unable to retrieve data.")

    End Try
    da.Dispose()
    Con.Close()
    Return dt
End Function

2 个答案:

答案 0 :(得分:2)

这有例外,但.Net中的最佳实践确实要求为大多数查询创建一个全新的连接对象。真。

除了通过连接池创建的好处(在上面的问题的评论中讨论),使用新的连接对象可以使您的应用程序更容易扩展到多个线程。想象一下,编写一个试图依赖单个全局连接对象的应用程序,然后突然想要生成一个单独的线程来处理后台长时间运行的任务,只是发现它已被阻止,或者本身阻止其他正常访问到数据库。更糟糕的是,想象一下尝试为Web应用程序执行此操作,并错误地将整个Application Domain(站点的所有用户)共享单个连接。

所以这是您现有代码正确的事情 但是,现有方法存在两个严重问题。

首先,作者似乎不了解何时打开以及何时关闭连接。使用.Fill()方法会使这一点变得复杂,因为this method will open and close your connection all on its own. 1 使用此方法时,没有充分的理由看到对.Open()的单个调用,{{1在该方法中,或.Close() 任何地方。如果不使用.Dispose()方法,则应始终将连接作为.Fill()块的一部分关闭:最简单的方法是使用Finally块。

第二个是SQL注入。所写的方法不允许在查询中包含参数数据。它只允许完成的SQL命令字符串。这实际上迫使您编写的代码非常容易受到SQL注入攻击。如果您还不知道SQL注入攻击是什么,请停止其他任何您正在做的事情并花些时间搜索该短语。

让我建议一种替代方法来解决这些问题:

Using

1 请参阅“备注”部分的第一段。

答案 1 :(得分:0)

这不是一个真实的回答"对我自己的问题,但我有一些东西需要添加,我想添加一些代码。

To Joe:谢谢,我的代码几乎完全使用参数化查询。虽然我知道SQL注入攻击是什么,并且它们是一个非常重要的事情,但这是我的例外:过去我曾使用存储过程进行参数化查询,而且我讨厌写这些并且为了第一年,我的代码将仅由我的5名员工的小公司使用,这些公司是家庭成员......如果我出售软件,我计划稍后将所有内容切换到存储过程。这种方法更好,我可能根本不需要存储过程。

我特别喜欢优雅的参数化查询处理日期,因为我不必将日期转换为适当的文本。更容易。

Anopther的优势我看到了:有时是"保存按钮"必须执行插入或更新,具体取决于显示的记录是否为新记录。使用参数允许我编写两个备用的短基本查询,但是使用相同的参数来减少代码。

总的来说,这意味着查询字符串的代码密集型构造要少得多。

我没有的部分,我学会了在其他地方做的,是分配参数数组,调用程序,所以我在这里包含一个例子,希望其他人觉得它有用:

Dim query As String = "Select Phone from Employees where EmpNo = @EmployeeNumber and Age = @Age"
Dim params As SqlParameter() = {
New SqlParameter("@EmployeeNumber", txtEmployeeNumber.Value),
New SqlParameter("@Age", txtAge.Value)
}
Dim Phone as String = GetData(query, params).Rows.Item(0)