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

问题描述

我有以下代码

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()确实打开,然后关闭

我必须假设da.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

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

那么我必须处置连接对象吗? 我可以使用sqlAdaptor做到这一点吗?

由于在调用代码中我的da.Update()在进行更新之前仍需要该连接,因此我无法在上面的子处理中放置/关闭连接对象。

解决方法

那我该如何确保正确放置和关闭连接对象?

不用担心;这不是你的工作。 DataAdapter做到了,DataAdapter会清理它

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

否,由于上述原因

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

是的,除非您有充分的理由相信Microsoft的代码存在严重缺陷,并且您的类将受益于您的代码对它们创建的资源的微管理。

如果您想知道他们在内部做的事情,还可以阅读参考资料

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之类的东西。这里的主要用途是,您不是通过“字符串列名称”访问某些DataRow对象,而是拥有一个一流的VB.NET对象-Hotel,具有命名的类型属性,dapper可以从SQL查询创建它们并将其值直接放入SQL参数(现有代码中不存在的另一种东西)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...