代码之家  ›  专栏  ›  技术社区  ›  Albert D. Kallal

SqlDataAdapter更新和关闭连接-如何通过数据适配器关闭连接

  •  1
  • Albert D. Kallal  · 技术社区  · 5 年前

    我有以下代码:

    Dim da As SqlDataAdapter
    Dim rst As DataRow = MyrstEdit("SELECT * FROM tblHotels WHERE ID = 19",, da).Rows(0)
    
    rst("HotelName") = "My Cool"
    rst("FirstName") = "Albert"
    rst("City") = "Edmonton"
    
    da.Update(rst.Table)
    

    所以,上面的内容很好,很简短。而且效果相当不错。

    当然这是asp。net,然后将连接代码(我不必反复创建)等内容集中化也是一个相当不错的选择。为什么要在编码过程中处理连接,这样可以减少编码工作量。

    那么,我如何确保正确地处理和关闭连接对象?

    从阅读来看,既然我没有打开连接,那么

    Fill()会先打开,然后关闭。

    我得假设检察官。Update()还必须按逻辑打开,然后关闭连接。

    但是,在完成上述操作后,我仍然应该清理连接对象。

    问题: 在这里,处理sql数据适配器对象是否足以处理数据适配器正在使用的连接对象?

    如:

    da.Dispose()
    

    MyRstEdit的例行程序如下:

    Public Function MyrstEdit(strSQL As String, 
                              Optional strCon As String = "", 
                              Optional ByRef oReader As SqlDataAdapter = Nothing) As DataTable
    
        ' can pass custom connection string - if not passed, then default
        If strCon = "" Then
            strCon = GetConstr()   ' global func to get application con string
        End If
    
        Dim mycon As New SqlConnection(strCon)
        oReader = New SqlDataAdapter(strSQL, mycon)
        Dim rstData As New DataTable
        Dim cmdBuilder = New SqlCommandBuilder(oReader)
    
        Try
            oReader.Fill(rstData)
            oReader.AcceptChangesDuringUpdate = True
        Catch
        End Try
        Return rstData
    
    End Function
    

    因此,返回的SQLDataAdapter对象必须保持连接,因为上述例程中的作用域是有限的。

    那么我必须处理连接对象吗? 我能用SQLAdapter做这个吗?

    我无法处理/关闭上面sub中的连接对象,因为我的da。在我进行更新之前,调用代码中的Update()仍然需要该连接。

    0 回复  |  直到 5 年前
        1
  •  1
  •   Caius Jard    5 年前

    那么,我如何确保正确地处理和关闭连接对象?

    别担心;这不是你的工作。DataAdapter成功了DataAdapter会把它清理干净

    但是,在完成上述操作后,我仍然应该清理连接对象

    不,出于上述原因

    在这里,处理sql数据适配器对象是否足以处理数据适配器正在使用的连接对象?

    是的,除非你有充分的理由相信微软的代码有一个严重的缺陷,并且他们的类将从你的代码中受益,对他们创建的资源进行微观管理。。

    如果你想知道他们在内部做什么,你也可以阅读参考资料

    MyRstEdit的例行程序如下:

    很难理解它为什么以这种形式存在;您最好只是传递一个数据表,并在需要时创建数据适配器。 MyRstEdit 名字不好;它似乎不编辑任何内容,它总是用任何传入的适配器可能已经知道的内容(connstr和sql)覆盖传入的适配器,然后不做任何不能直接放入的事情

    Using da As New SqlDataAdapter("SELECT * FROM tblHotels WHERE ID = 19", GetConStr())
      Dim dt as New DataTable
      da.Fill(dt)
    
      Dim rst = dt(0)
      rst("HotelName") = "My Cool"
      rst("FirstName") = "Albert"
      rst("City") = "Edmonton"
    
      New SqlCommandBuilder(da)
      da.Update(rst.Table)
    End Using
    

    它所做的最有用的事情是应用一个命令生成器,但这只是一行代码,而且只需要更新。。

    也许您可以创建一个应用于DataAdapter的扩展方法,该方法获取第一行,因此您可以说:

    Using da As SqlDataAdapter("SELECT * FROM tblHotels WHERE ID = 19", GetConStr())
    
      Dim rst = da.FirstRow()
      rst("HotelName") = "My Cool"
      rst("FirstName") = "Albert"
      rst("City") = "Edmonton"
    
      New SqlCommandBuilder(da)
      da.Update(rst.Table)
    
    End Using
    

    但它并没有节省很多“仅仅使用它如何MS打算”,仍然有块的“数据列访问字符串,因此智能感知无法帮助”在中间。

    如果你想找到让你的SqlDataAdapter生活更轻松的方法,不妨跳过它,转而看看Dapper;SqlConnection上的一组扩展方法,将类映射到:

    Using c as New SqlConnection(GetConStr())
    
        Dim h = Await c.SingleAsync(Of Hotel)("SELECT * FROM tblHotels WHERE ID = @id", New With { .ID = 19 } )
    
        h.HotelName = "My Cool"
        h.FirstName = "Albert"
        h.City = "Edmonton"
    
        Await c.ExecuteAsync("UPDATE tblHotels SET HotelName = @HotelName, FirstName = @FirstName, City = @City WHERE ID = @ID", h)
    End Using
    
    

    您仍然需要编写查询,但这是一次性操作,或者您可以查看类似Dapper Contrib的内容。。这里的主要用途是使用一级VB,而不是通过“字符串列名”访问某些DataRow对象。NET对象-Hotel,带有命名类型的proeprites,dapper可以从SQL查询中创建它们,并将它们的值直接放入SQL参数中(现有代码中缺少的另一项功能)

    推荐文章