I DbDataAdapter di .NET si basano su oggetti di tipo DbCommand per selezionare, aggiornare, aggiungere ed eliminare le informazioni dalla base di dati sottostante. Gli oggetti DbCommand, a loro volta, mantengono un riferimento alla DbConnection che corrisponde all'origine dati in questione. Tale connessione non deve necessariamente essere aperta prima di richiamare i metodi del DbDataAdapter: nel caso in cui sia chiusa quando si eseguono i metodi del DbDataAdapter, viene aperta automaticamente, per poi essere richiusa al termine dell'operazione.
E' possibile verificare questo comportamento con un semplice esempio. Consideriamo il seguente stralcio di codice:
1 SqlConnection db = new SqlConnection(@"Data Source=192.168.0.212\SQLEXPRESS;
2 Initial Catalog=Northwind;Integrated Security=True;");
3 db.StateChange += new StateChangeEventHandler(db_StateChange);
4 db.Open();
5
6 SqlCommand cmd = db.CreateCommand();
7 cmd.CommandType = CommandType.Text;
8 cmd.CommandText = "SELECT * FROM Customers;";
9
10 SqlDataAdapter da = new SqlDataAdapter(cmd);
11 DataSet ds = new DataSet();
12 da.Fill(ds, "Customers");
13
14 private void db_StateChange(object sender, StateChangeEventArgs e)
15 {
16 Response.Write(e.CurrentState + "<br/>");
17 }
In questo caso, la connessione viene manualmente aperta (riga 4) prima di richiamare i metodi del DataAdapter: l'evento StateChange viene generato una sola volta, poiché la connessione, essendo già aperta prima di richiamare il metodo Fill (riga 12), rimane in questo stato anche al termine dell'operazione.
Commentando la riga 4, invece, il comportamento cambia: la connessione verrà aperta per l'esecuzione del metodo Fill (riga 12) e sarà chiusa automaticamente al termine dell'operazione. In altri termini, l'evento StateChange viene generato due volte.