Come lavorare con ADO.Net in modalità disconnessa

Il framework di accesso ai dati ADO.Net di Microsoft è in uso da oltre due decenni. È possibile sfruttare ADO.Net per eseguire operazioni CRUD su un'ampia varietà di database dall'ambiente gestito di .Net CLR.

Un fornitore di dati è un componente software che incapsula i protocolli utilizzati per connettersi e interagire con il database sottostante dall'ambiente gestito. Alcuni dei provider di dati più diffusi includono: SQL Server Data Provider, Oracle Data Provider e OLEDB Data Provider. ADO.Net può funzionare sia in modalità connessa che disconnessa.

Una modalità operativa connessa in ADO.Net è quella in cui la connessione al database sottostante è attiva per tutta la durata dell'operazione. Nel frattempo, una modalità operativa disconnessa è quella in cui ADO.Net recupera i dati dal database sottostante, archivia i dati recuperati temporaneamente nella memoria e quindi chiude la connessione al database.

Quando si lavora con ADO.Net in modalità operativa disconnessa, in genere si utilizza DataAdapter, DataSet, DataTable e DataTableReader. Mentre il DataAdapter funge da ponte tra l'applicazione e il database, un DataSet è una rappresentazione disconnessa in memoria del database e può contenere una o più istanze DataTable. Un DataTableReader è simile a un DataReader tranne per il fatto che funziona in modalità disconnessa.

Analizziamo un po 'di codice

Ne abbiamo abbastanza dei concetti: entriamo nel codice. Il frammento di codice seguente mostra come recuperare i dati da un database in modalità disconnessa. Si noti che questo esempio si connette al database AdventureWorks solo a scopo illustrativo.

static void Main(string[] args)

        {

            string connectionString = ConfigurationManager.ConnectionStrings["AdventureWorksDB"].ConnectionString;

            try

            {

                using (SqlConnection sqlConnection = new SqlConnection(connectionString))

                {

                    sqlConnection.Open();

                    SqlDataAdapter sqlDataAdapter = new SqlDataAdapter("SELECT *  FROM [AdventureWorks2014].[HumanResources].[Department]", sqlConnection);

                    DataSet dataSet = new DataSet();

                    sqlDataAdapter.Fill(dataSet);

                }                

            }

            catch (Exception ex)

            {

                //Write code here to handle exception

            }

        }

Nell'elenco di codice precedente, viene stabilita una connessione al database utilizzando un'istanza della classe SqlConnection. Quindi viene creata un'istanza DataAdapter che viene utilizzata per popolare un'istanza DataSet utilizzando il metodo Fill () della classe DataAdapter. La connessione al database viene chiusa automaticamente quando il controllo esce dal blocco "using" poiché il metodo Dispose () viene richiamato automaticamente sull'istanza SqlConnection. I dati archiviati nell'istanza di DataSet risiedono nella memoria e non dipendono da una connessione di database attiva poiché DataSet funziona in modalità disconnessa. Una volta che i dati sono stati recuperati dal database e archiviati nella memoria in un'istanza DataSet, è anche possibile modificare i dati se lo si desidera e quindi persistere nuovamente i dati quando necessario.

DataRow dataRow = dataSet.Tables[0].NewRow(); //Creates a new data row

//You can now specificare la values for each of the columns of the data row

dataSet.Tables[0].Rows.Add(dataRow); //Add the data row

sqlDataAdapter.Update(dataSet); // Inserts a new record

Notare che è possibile utilizzare il blocco "using" sui tipi che implementano l'interfaccia IDisposable. L'intero blocco "using" è racchiuso in un blocco try - catch per gestire le eccezioni che possono sorgere quando il programma è in esecuzione. Si noti che la stringa di connessione in questo esempio viene recuperata da un file di configurazione: è buona norma isolare la stringa di connessione dal codice dell'applicazione. Puoi anche crittografare la stringa di connessione, se necessario.

È anche possibile popolare un DataTable nello stesso modo in cui si popola un DataSet. Ecco un esempio che lo illustra.

string connectionString = ConfigurationManager.ConnectionStrings["AdventureWorksDB"].ConnectionString;

            try

            {

                using (SqlConnection sqlConnection = new SqlConnection(connectionString))

                {

                    sqlConnection.Open();

                    SqlDataAdapter sqlDataAdapter = new SqlDataAdapter("SELECT *  FROM [AdventureWorks2014].[HumanResources].[Department]", sqlConnection);

                    DataTable dataTable = new DataTable();

                    sqlDataAdapter.Fill(dataTable);                   

                }                

            }

            catch (Exception ex)

            {

                //Write code here to handle exception

            }

Un DataTableReader combina il meglio di entrambi i mondi, cioè è come un DataReader che funziona in modalità disconnessa ed è più veloce sia di DataTable che di DataReader. Per creare un DataTableReader tutto ciò che devi fare è invocare il metodo CreateDataReader () sull'istanza DataTable.

DataTableReader dataTableReader = dataTable.CreateDataReader();

Il listato di codice seguente mostra come visualizzare i nomi di tutti i reparti utilizzando DataTableReader.

static void Main(string[] args)

        {

            string connectionString = ConfigurationManager.ConnectionStrings["AdventureWorksDB"].ConnectionString;

            try

            {

                using (SqlConnection sqlConnection = new SqlConnection(connectionString))

                {

                    sqlConnection.Open();

                    SqlDataAdapter sqlDataAdapter = new SqlDataAdapter("SELECT *  FROM [AdventureWorks2014].[HumanResources].[Department]", sqlConnection);

                    DataTable dataTable = new DataTable();

                    sqlDataAdapter.Fill(dataTable);

                    DataTableReader dataTableReader = dataTable.CreateDataReader(); 

                    while(dataTableReader.Read())

                    {

                        Console.WriteLine(dataTableReader["Name"].ToString());

                    }      

                }                

            }

            catch (Exception ex)

            {

                //Write code here to handle exception

            }

            Console.Read();

        }