Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ADO.NET Best Practices for Connection and DataAdaptor Object Scope

Tags:

ado.net

This is my first post on StackOverflow, so please be gentle...

I have some questions regarding object scope for ADO.NET.

When I connect to a database, I typically use code like this:

OleDbConnection conn = new OleDbConnection("my_connection_string");
conn.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * from Employees", conn);
OleDbCommandBuilder cb = new OleDbCommandBuilder(adapter);
DataTable dt = new DataTable();
adapter.Fill(dt);
conn.Close();
conn.Dispose();

Let's say that I bind the resulting DataTable to a grid control and allow my users to edit the grid contents. Now, when my users press a Save button, I need to call this code:

adapter.Update(dt);

Here are my questions:

1) Do I need to retain the adapter object that I created when I originally loaded the datatable, or can I create another adapter object in the Save button click event to perform the update?

2) If I do need to retain the original adapter object, do I also need to keep the connection object available and open?

I understand the disconnected model of ADO.NET - I'm just confused on object scope when it's time to update the database. If someone could give me a few pointers on best practices for this scenario, I would greatly appreciate it!

Thanks in advance...

like image 376
Mark Lansdown Avatar asked Feb 27 '09 09:02

Mark Lansdown


1 Answers

1) You don't need the same DataAdapter, but if you create a new one it must use the same query as its base.

2) The DataAdapter will open its connection if the connection is closed. In that case it will close the connection again after it is done. If the connection is already open it will leave the connection open even after it is done.

Normally you would work as in your example. Create a Conneciton and a DataAdapter, fill a DataTable and dispose of the Connection and the DataAdapter afterwards.

Two comments to your code:

  • You don't need the CommandBuilder here since you only do a select. The command builder is only needed if you want to generate Insert, Update or Delete statements automatically. In that case you also need to set the InsertCommand, UpdateCommand or DeleteCommand on the DataAdapter manually from the CommandBuilder.
  • Second. Instead of calling Dispose manually you should use the Using clause. It ensures that your objects will be disposed of even if an exception is thrown.

Try to change your code to this:

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

Note that I define the DataTable outside the using clauses. This is needed to ensure that the table is in scope when you leave the usings. Also note that you don't need the Dispose call on the DataAdapter or the Close call on the Connection. Both are done implicitly when you leave the usings.

Oh. And welcome to SO :-)

like image 134
Rune Grimstad Avatar answered Oct 06 '22 22:10

Rune Grimstad