2012-04-12 16 views
3

Ich habe eine SQL-Klasse, die eine Verbindung zur DB herstellt und eine DataTable retreives. Mir ist bewusst, dass die SqlConnection nach dem Beenden entsorgt werden muss. Ich weiß, dass dies mit einem using Block getan werden kann, aber ist es auch akzeptabel, den Dispose() Aufruf innerhalb des Destruktors dieser Klasse zu setzen?SQL-Verbindung wird freigegeben

Herre ist mein Code:

public class SQLEng 
{ 

    //Connection String Property 
    //Must be set to establish a connection to the database 
    public string ConnectionString{ get; set; } 
    SqlConnection _Conn; 

    //Overridden Constructor enforcing the Connection string to be set when created 
    public SQLEng(string connectionString) 
    { 
     ConnectionString = connectionString; 
     _Conn = new SqlConnection(connectionString); 
    } 

    //ensure the SqlConnection is disposed when destructing this object 
    public ~SQLEng() 
    { 
     _Conn.Dispose(); 
    } 

    //various other methods to get datatables etc... 
} 

Grundsätzlich möchte ich eine Klassenvariable SqlConnection haben, anstatt das SqlConnection innerhalb jeder Methode zu instanziiert, die die DB zugreift. Ist das eine gute Übung?

+3

Es wird nicht garantiert, dass der Destruktor aufgerufen wird. Sie sollten wahrscheinlich 'SQLEng' selbst verfügbar machen und von Benutzern von _it_ abhängen, um die Entsorgung zu handhaben. –

+0

Danke @ m.babcock, ich denke, ich werde Yucks Rat befolgen und die Verbindung nur öffnen und schließen, wenn es erforderlich ist. Ich würde lieber nicht Dispose() jedes Mal aufrufen müssen, wenn ich DB-Zugriff in anderen Klassen brauche - einfach versuchen, es in dieser Klasse einzupacken. – Simon

Antwort

8

Ihr Entwurf regt das Hängen an einem (vermutlich offenen) SqlConnection für lange Zeit an. Best Practice ist eine Verbindung zu öffnen, bevor Sie sie benötigen und dann freigeben (schließen und entsorgen), sobald Sie fertig sind.

Ja, mit der Erstellung neuer Verbindungen ist ein gewisser Aufwand verbunden. connection pooling erleichtert viel von dieser Bearbeitungszeit. Schlimmer noch, viele Verbindungen auf dem Server aufrecht zu erhalten.

+0

+1, danke für den Rat. – Simon

0

Wenn Sie die SQL Connection-Klasse umbrechen möchten, implementieren Sie IDisposable und rufen Sie die Verbindung Dispose() in Ihrer eigenen Dispose() -Methode auf. Weitere Informationen finden Sie hier:

Properly disposing of a DbConnection

Zur Frage, ob oder nicht diese gute Praxis ist - gut, wenn alle Ihre tun, um die SQL-Verbindung in einer anderen Klasse eingewickelt ist, ich bin nicht sicher, was Sie zu erreichen. Alle Ihre Methoden benötigen weiterhin Zugriff auf die Instanz dieser Klasse. In diesem Fall können sie selbst auf die Instanz des Verbindungsobjekts zugreifen.

1

Mit Blick auf die Quelle für die Enterprise Library (aus dem MS Patterns & Practices-Team) erstellt der DAAB nach Bedarf eine Verbindung und disponiert sie so schnell wie möglich.

public virtual int ExecuteNonQuery(DbCommand command) 
{ 
    using (var wrapper = GetOpenConnection()) 
    { 
     PrepareCommand(command, wrapper.Connection); 
     return DoExecuteNonQuery(command); 
    } 
} 

protected DatabaseConnectionWrapper GetOpenConnection() 
{ 
    DatabaseConnectionWrapper connection = TransactionScopeConnections.GetConnection(this); 
    return connection ?? GetWrappedConnection(); 
} 

Also ich würde sagen, das ist eine Best Practice. In den meisten Fällen wird lediglich die Verbindung zum Verbindungspool zurückgegeben, sodass die Verbindung eigentlich nicht geschlossen ist.