Frage

mich gefragt, ob es empfehlenswert ist, eine Datenbankverbindung Objekt zu übergeben um (an anderen Module) oder lassen Sie das Verfahren (in dem anderen Modul) sorgt sie für die Einrichtung. Ich bin Neigung in Richtung der Methode lassen es einrichten müssen den Status der Verbindung zu überprüfen, bevor es verwendet wird, und mit nur der Anrufer alle erforderlichen Daten an die aufrufende Methode übergeben, die die Verbindung zur Einrichtung benötigt werden würde.

War es hilfreich?

Lösung

Persönlich mag ich fest scoped Verbindungen verwenden; öffnen sie spät, sie verwenden, und schließen Sie sie (in einem „mit“ Block, die alle innerhalb der lokalen Methode). Connection-Pooling mit Wiederverwendung der Verbindung in den meisten Fällen befassen wird, so gibt es keinen wirklichen Aufwand in diesem Ansatz.

Der Hauptvorteil Verbindungen im Vorbeigehen verwendet , so zu sein, dass Sie die Transaktion um passieren könnten; jedoch TransactionScope ist ein einfacher Weg, um eine Transaktion zwischen Methoden des Teilens.

Da die Klassen Implementierung spezifisch sind, würde ich jeder schreiben zu öffnen eigene Mutter Transaktion ist. Ansonsten können Sie die ado.net Factory-Methoden verwenden, um den entsprechenden Typen aus der Konfigurationsdatei (der Providername) zu erstellen.

Andere Tipps

Ich persönlich wie ein Stapel meiner aktuellen offene Verbindung und Transaktionen auf dem Thread Local Storage SetData und GetData verwenden. Ich definiere eine Klasse, die meine Verbindungen zur Datenbank verwaltet und erlauben es den dispose Muster zu verwenden. Das spart mir die Notwendigkeit, Verbindungen und Transaktionen um passieren, was etwas ist, das ich clutters denken und verkompliziert den Code.

würde ich dringend empfehlen gegen es verlassen zu den Methoden nach oben Verbindungen zu öffnen jedes Mal, wenn sie Daten benötigen. Es führt zu einer wirklich schlechten Situation, in der es sowohl schwierig ist, Transaktionen in der gesamten Anwendung und zu viele Verbindungen zu verwalten geöffnet und geschlossen werden (ich weiß, über Connection-Pooling, es ist immer noch teurer eine Verbindung aus dem Pool zu sehen, als es ist ein Objekt wieder zu verwenden)

Also ich am Ende etwas in dieser Richtung haben (total ungetestet):

class DatabaseContext : IDisposable {

    List<DatabaseContext> currentContexts;
    SqlConnection connection;
    bool first = false; 

    DatabaseContext (List<DatabaseContext> contexts)
    {
        currentContexts = contexts;
        if (contexts.Count == 0)
        {
            connection = new SqlConnection(); // fill in info 
            connection.Open();
            first = true;
        }
        else
        {
            connection = contexts.First().connection;
        }

        contexts.Add(this);
    }

   static List<DatabaseContext> DatabaseContexts {
        get
        {
            var contexts = CallContext.GetData("contexts") as List<DatabaseContext>;
            if (contexts == null)
            {
                contexts = new List<DatabaseContext>();
                CallContext.SetData("contexts", contexts);
            }
            return contexts;
        }
    }

    public static DatabaseContext GetOpenConnection() 
    {
        return new DatabaseContext(DatabaseContexts);
    }


    public SqlCommand CreateCommand(string sql)
    {
        var cmd = new SqlCommand(sql);
        cmd.Connection = connection;
        return cmd;
    }

    public void Dispose()
    {
        if (first)
        {
            connection.Close();
        }
        currentContexts.Remove(this);
    }
}



void Test()
{
    // connection is opened here
    using (var ctx = DatabaseContext.GetOpenConnection())
    {
        using (var cmd = ctx.CreateCommand("select 1"))
        {
            cmd.ExecuteNonQuery(); 
        }

        Test2(); 
    }
    // closed after dispose
}

void Test2()
{
    // reuse existing connection 
    using (var ctx = DatabaseContext.GetOpenConnection())
    {
        using (var cmd = ctx.CreateCommand("select 2"))
        {
            cmd.ExecuteNonQuery();
        }
    }
    // leaves connection open
}

Für die automatisierten Testzwecke ist es in der Regel einfacher, es in zu übergeben. Dies nennt man Dependency Injection .

Wenn Sie Tests schreiben müssen, können Sie ein Mock-Datenbankverbindungsobjekt erstellen und dass anstelle der realen passieren. Auf diese Weise Ihre automatisierten Tests werden nicht auf einer tatsächlichen Datenbank verlassen, die jedes Mal mit Daten neu besiedelt werden muss.

ich persönlich arbeiten, um meine Datenzugriff so viel wie möglich, jedoch zu zentralisieren, wenn nicht möglich, dass ich immer eine neue Verbindung in den anderen Klassen öffnen, wie ich, dass es finden zu viele andere Dinge, die in die Quere kommen kann beim Passieren das tatsächliche Verbindungsobjekt.

Hier ist ein wenig mehr Einblick in dieses Problem. Ich habe eine Klasse, die DB-Verbindungen verwaltet und habe zwei Klassen, die eine Schnittstelle zu implementieren. Eine der Klassen ist für SQL und das andere ist von OLAP. Der Manager ist derjenige, der die Verbindung zu nutzen weiß, so könnte es die genaue Verbindung mit dem Typ übergeben, oder der Typ kann seine eigene Verbindung erstellen.

Sie können Verbindungsobjekte ohne Probleme (zum Beispiel Microsoft Enterprise Library ermöglicht statische Methode ruft in einer Verbindung vorbei) oder Sie können verwalten sie sich von außen bis zu Ihrem Design passieren, da keine technischen Kompromisse richten werden.

für Portabilität Darauf achten, dass eine bestimmte Verbindung, wenn Ihre Lösung passieren zu anderen Datenbanken (dh noch kein eigenes SqlConnection übergibt es Sie planen, mit anderen Datenbanken arbeiten) portiert werden

, um die Verbindung aufzubauen ist möglicherweise teuer und fügt möglicherweise eine Rundreise. Also, noch einmal, was möglicherweise die bessere Gestaltung ist das Verbindungsobjekt zu übergeben.

Ich sage möglicherweise, weil, wenn Sie ein Microsoft ADO App, werden Sie wahrscheinlich einen Verbindungspool mit ....

Ich würde vorschlagen, dass Sie zwischen dem Verbindungsobjekt und seinem Zustand zu unterscheiden (offen, geschlossen).

Sie können eine einzelne Methode (oder Eigenschaft), die die Verbindungszeichenfolge von web.config liest. Unter Verwendung der gleichen Version der Verbindungszeichenfolge stellt sicher, jedes Mal, wenn Sie von Connection Pooling profitieren werden.

diese Methode aufrufen, wenn Sie eine Verbindung öffnen müssen. Im allerletzten Moment, nachdem alle der SqlCommand Eigenschaften einrichten, öffnen Sie die Verbindung, verwenden Sie es, und schließen Sie es dann. In C # können Sie die Anweisung using verwenden, um sicherzustellen, dass die Verbindung geschlossen wird. Wenn nicht, sollten Sie die Verbindung in einem finally-Block zu schließen.

Ich würde die web.config verwenden

<configuration>
    <connectionStrings>
        <add name="conn1" providerName="System.Data.SqlClient" connectionString="string here" />
        <add name="conn2" providerName="System.Data.SqlClient" connectionString="string here" />
    </connectionStrings>
</configuration>

Dann können Sie es von überall in der Anwendung verweisen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top