E' sicuramente una best practice quella di chiudere un datareader quando questo è stato utilizzato. Consideriamo però il seguente snippet di codice:
DBConnection connection;
using (connection = factory.CreateConnection())
{
DBCommand cmd = connection.CreateCommand();
// some code
DBDataReader dr = cmd.ExecuteReader();
// some code
}
Console.WriteLine(connection.State);
Il cursore non viene esplicitamente chiuso, questo è vero, ma viene comunque invocata la dispose della connection verso il DB.
Con SqlClient questo snippet funziona come previsto, stesso dicasi per OleDbClient e per Oracle.DataAccess: lo snippet stampa "Closed" sulla console e, se si disabilita il connection pool, si può notare come all'esterno del blocco using non ci sia alcuna connessione attiva presso il DB Server.
Con System.Data.OracleClient, invece, si verifica un comportamento anomalo: nonostante la connection risulti comunque chiusa, fisicamente al termine dello snippet si può verificare come rimanga una connessione appesa e quindi non riutilizzabile neanche dal connection pool. Questo non accade chiudendo esplicitamente il datareader, con una leggera variante allo snippet di prima:
DBConnection connection;
using (connection = factory.CreateConnection())
{
DBCommand cmd = connection.CreateCommand();
// some code
using (DBDataReader dr = cmd.ExecuteReader())
{
// some code
}
}
Console.WriteLine(connection.State);
Ovviamente me ne sono accorto in produzione :-(