问题描述
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参数(现有代码中不存在的另一种东西)