【问题标题】:.Net ADO Connection Class.Net ADO 连接类
【发布时间】:2011-08-12 08:44:40
【问题描述】:

我创建了一个连接类,它应该将数据表/数据读取器等返回到我的网页。我担心使用此类无法正确关闭连接。这是课程:

Imports Microsoft.VisualBasic

Namespace myConnection
  Public Class DB

      Public Shared Function GetConnStr()
                    Return "server=foobar"
      End Function


      Public Shared Function OpenConn()
                    Return New System.Data.SqlClient.SqlConnection( GetConnStr )
      End Function

      Public Shared Function OpenReader(SQL As String)

                    Dim conn 
                    conn = OpenConn
                    conn.Open

                    Return New System.Data.SqlClient.SqlCommand(SQL, conn).ExecuteReader(System.Data.CommandBehavior.CloseConnection)

      End Function

      Public Shared Function OpenTable(SQL As String)

                    Dim conn 
                    conn = OpenConn
                    conn.Open

                    Dim dr As System.Data.SqlClient.SqlDataReader = New System.Data.SqlClient.SqlCommand(SQL, conn).ExecuteReader(System.Data.CommandBehavior.CloseConnection)
                    Dim dt As System.Data.DataTable = New System.Data.DataTable()
          dt.Load(dr)

                    Return dt 

      End Function

      Public Shared Function ExecuteSQL(SQL As String)

                    Dim conn 
                    conn = OpenConn
                    conn.Open

                    Return New System.Data.SqlClient.SqlCommand(SQL, conn).ExecuteNonQuery()

      End Function


  End Class
End Namespace

这是我的使用方法:

rst = conn.OpenReader(SQL)
While rst.Read  
end while
rst.close

我担心一旦我投入生产,连接将无法正常关闭,我的网站将会失败。我是 .net 新手,这门课的校长有什么问题吗?

【问题讨论】:

  • 编写自己的连接类听起来是个坏主意。
  • 编写 Connection Helper 类是可以的,只要您记得始终在使用它的任何地方明确关闭和处置您的连接,而不仅仅是在您的基类上。
  • Andomar,你能详细说明为什么这是个坏主意吗?费利佩,在我的例子中 rst.Close 就足够了,还是我必须做 rst.Close 和 rst.Dispose ?
  • Close() 方法确实关闭了连接,但是它将对象留在内存中以防以后使用,Dipose() 方法消除了对象及其资源,因此不能不再使用了。

标签: asp.net sql-server vb.net ado.net


【解决方案1】:

您是对的:您的连接不会以这种方式关闭。更糟糕的是,通过只接受 sqlcommand 的字符串,您将面临 sql 注入安全漏洞。作为一个更好的模式的例子,我用来填充数据表的代码看起来更像这样:

Public Function GetDataTable(ByVal sql As String, ByVal AddParameters As Action(Of SqlParameterCollection)) As DataTable
    Dim result As New DataTable()
    Using cn As SqlConnection = OpenConn(), _
          cmd As New SqlCommand(sql, cn)

        AddParameters(cmd.Parameters)

        Using rdr As SqlDataReader = cmd.ExecuteReader
            result.Load(rdr)
        End Using
    End Using
    Return result
End Function

然后我会这样调用代码:

Dim data As DataTable = GetDataTable("SELECT * FROM SomeTable WHERE ID= @ID", _ 
       Sub(p)
           p.Add("@ID", SqlDbType.Int).Value = 12345
       End Sub )

我在 C# 中有类似的 SqlDataReader 代码,但它需要使用迭代器块,并且该功能 不适用于 VB只有 just added to VB.Net 与 Visual Studio 2010 和 Async 的服务包CTP 几周前推出。重要的是,我使用 Using 块正确封装了 sql 连接,并且代码鼓励正确使用查询参数。

【讨论】:

    【解决方案2】:

    不幸的是,我同意其他 cmets 之一。为什么要编写自己的连接类?

    使用 ADO.NET EF 或 LINQ To SQL 来管理上下文中的连接。

    如果您继续做您正在做的事情,请将您的连接包装在 Using 块中。

    【讨论】:

      【解决方案3】:

      我使用一个模块来调用数据库,如果你使用多个表单可以节省很多行...

      这是我的模块形式:

      Public cn As OleDbConnection
      
      Public Sub InitDatabase()
          Dim sDBase As String = "DB.mdb"
          cn= New OleDbConnection
          cn.ConnectionString = "Provider=Microsoft.JET.OLEDB.4.0; Data Source=" & sDBase
      End Sub
      

      然后调用数据库使用这个:

      Private ds As New DataSet
      Private da As New OleDbDataAdapter
      
      modWijnen.InitDatabase()
      
          Dim cm As New OleDbCommand("Select * from Table1", cn)
          da = New OleDbDataAdapter(cm)
      
          If (ds.Tables.Contains("Table1") = False) Then
              da.Fill(ds, "Table1")
          End If
      

      我希望这对你有所帮助......

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-30
        • 2012-11-08
        • 2021-08-28
        相关资源
        最近更新 更多