Domanda

Di solito uso un codice come questo:

using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
{
   var command = connection.CreateCommand();
   command.CommandText = "...";
   connection.Open();
   command.ExecuteNonQuery();
}

Il mio comando verrà automaticamente eliminato? Oppure no e devo inserirlo nel blocco usando ? È necessario disporre di SqlCommand ?

È stato utile?

Soluzione

Basta fare questo:

using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
using(var command = connection.CreateCommand())
{
   command.CommandText = "...";
   connection.Open();
   command.ExecuteNonQuery();
}

Non chiamare dispose sul comando non farà nulla di male. Tuttavia, chiamando Dispose su di esso sopprime la chiamata al finalizzatore , facendo sì che la chiamata disponga di un miglioramento delle prestazioni.

Altri suggerimenti

La politica più sicura è chiamare sempre Dispose () su un oggetto se implementa IDisposable , esplicitamente o tramite un blocco using. Ci possono essere casi in cui non è richiesto, ma chiamarlo comunque non dovrebbe mai causare problemi (se la classe è scritta correttamente). Inoltre, non si sa mai quando un'implementazione può cambiare, il che significa che laddove la chiamata non era precedentemente richiesta, ora è sicuramente richiesta.

Nell'esempio che hai fornito, puoi aggiungere un blocco using interno extra per il comando, oltre a mantenere il blocco using esterno per la connessione.

Sì, dovresti, anche se l'implementazione non sta facendo molto, non sai come sarà cambiata in futuro (ad esempio versioni più recenti del framework). In generale, dovresti disporre tutti gli oggetti che implementano IDisposable per essere al sicuro.

Tuttavia, se l'operazione è differita e non si controlla l'intero ambito (ad esempio quando si lavora in modo asincrono o quando si restituisce un SqlDataReader o giù di lì), è possibile impostare il CommandBehavior in CloseConnection in modo che, non appena il lettore ha terminato, la connessione sia correttamente chiusa / disposta per te.

Puoi scoprire questo tipo di cose usando Reflector o dotPeek o < a href = "https://referencesource.microsoft.com/" rel = "nofollow noreferrer"> https://referencesource.microsoft.com/ .

Ho avuto un piccolo scavo (ti suggerirei di scavare te stesso per essere completamente sicuro del resto, anche se non ci ho provato tanto) e sembra che quando uccidi una connessione non ci sia tutti i bambini associati a tale connessione. Inoltre, in realtà non sembra che l'eliminazione di un comando faccia davvero tanto. Imposta un campo su null, si stacca da un contenitore (questo potrebbe impedire una perdita di memoria gestita) e genera un evento (questo potrebbe essere importante ma non riesco a vedere chi sta ascoltando questo evento).

In entrambi i casi è buona norma utilizzare questa roba in un blocco using o assicurarsi di eliminarla usando un modello dispose nell'oggetto che contiene la connessione (se si intende mantenere il comando per un po ').

In pratica, puoi saltare Dispose . Non libera alcuna risorsa. Non sopprime nemmeno la finalizzazione poiché Il costruttore di comandi SQLC lo fa .

In teoria, Microsoft potrebbe cambiare l'implementazione per contenere una risorsa non gestita, ma spero che escano con un'API che si sbarazzi della classe base Component molto prima che lo facciano che.

Secondo me, chiamare Dispose sia per SqlConnection sia per SqlCommand è una buona pratica, usare il codice sotto

using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
try{
    using(var command = connection.CreateCommand())
    {
       command.CommandText = "...";
       connection.Open();
       command.ExecuteNonQuery();
    }
}
catch(Exception ex){ //Log exception according to your own way
    throw;
}
finally{
    command.Dispose();
    connection.Close();
    connection.Dispose();
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top