ADO.NET 连接和 DataAdaptor 对象范围的最佳实践 - 跟进

ADO.NET Best Practices for Connection and DataAdaptor Object Scope - follow-up

我的问题与 Mark Lansdown 前段时间提出的问题完全相同。 Mark's question

那个帖子里的答案有点帮助,但让我仍然非常困惑;特别是因为它与使用“使用”块的推荐做法有关。

第一个答案似乎表明应该在 using 块中创建 Connection 对象和 DataAdapter 对象...

DataTable dt = new DataTable();
using (OleDbConnection conn = new OleDbConnection("my_connection_string"))
using (OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * from Employees", conn))
{
  adapter.Fill(dt);    
}

因此,DataTable 对象被保留,但 DataAdapter 和 Connection 对象在 table 被填充的瞬间超出范围。

然而后续的回答表明应该保留 DataAdapter 对象。这对我来说非常有意义,因为在我看来,DataAdapter 的设计确实考虑到了处理多个命令。

所以这给我留下了多个问题: 顺便说一句,我正在使用 vb.net 和 SQL Server

问题 1) 为了保留 DataAdapter 对象,这是否意味着我不能使用 using 块创建它?

问题 2) 为了创建 DataAdapter 的实例,我不需要 Connection 对象的实例吗?这会使使用 using 块创建 Connection 对象变得不切实际?

如何在这样的代码中实现 using 块?

Private Class frmMain

  Dim adapter as SqlDataAdapter
  Dim conn as SqlConnection

  Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles Me.Load
    
    conn = new SqlConnection("My_Connection_String")
    adapter = new SqlDataAdapter("Select * from Employees", conn)
    
    adapter.fill(MyDataSet, MyTableName)

  End Sub
  
  Private Sub SaveButtton_Click(sender as Object, e As EventArgs) Handles SaveButton.Click
    adapter.Update(MyTableName)
  End Sub
End Class 

我在 msdn 上看到了所有这些的一堆示例代码,我看到的每个示例代码都使用块合并,但总是通过代码创建 table 并通过代码执行更新,所有这些都在 using 块中,看起来对我来说,它在现实世界中永远行不通。

感谢任何建议。

a follow-on answer indicated that the DataAdapter Object should be retained...

Question 1) In order to retain the DataAdapter object doesn't that mean I cannot create it with a using block?

没有。响应是有缺陷的。请记住,DataAdpater 是在 .Net 1.0 中。这时候没有好的方法来处理你的对象,所以你尽力了。为 .Net 2.0 添加了 Using 块和良好的 IDisposable 支持,这导致了工作方式的方向改变。是的,DataAdapter 可以有不同类型的查询,并且能够支持更长的生命周期(如果您确实需要的话),但是以这种方式使用它不再是一个好的选择。

如果您确实需要,您仍然可以稍后创建另一个 DataAdapter(如果您需要它用于不同类型的查询),或者您可以使用 ExecuteNonQuery() 来处理 DELETE、INSERT 和 UPDATE 等操作。但是,如果您希望框架为您完成更多此类工作,那么您真的应该选择完整的 ORM。如果您想在代码中编写自己的 SELECT 语句,通常最好也手动编写自己的 INSERT、UPDATE 和 DELETE(等)语句(并确保使用参数化查询! ).

Question 2) In order to create an instance of a DataAdapter don't I need an instance of a Connection object which would make it impractical to create the Connection object with a using block?

How would I implement the using blocks in code like this?

不要那样写代码。我不会重复自己,而是 link 之前的回答解释了原因:

https://softwareengineering.stackexchange.com/questions/142065/creating-database-connections-do-it-once-or-for-each-query/398790#398790

但简短的版本是 ADO.Net 连接对象是连接池中“更重”和更昂贵项目的薄包装。当您尝试 re-use 整个 class 或应用程序的连接时,您会以牺牲更大的实际底层连接为代价,在相对便宜的包装器中获得效率。每次都创建一个新连接确实要好得多。只应为 re-use.

保留连接字符串

every sample code I saw incorporated using blocks but always created a table via code and performed updates via code all inside the using blocks which seems to me like it could never work in the real world.

我向你保证,它工作得很好。同样,如果您不喜欢它,也许您正在寻找像 EntityFramework.

这样的完整 ORM