3 Stimmen

Effizienterer Datenbankzugriff

Ich bin neu in Datenbanken und Linq, so dass mein Problem als trivial angesehen werden kann. Ich beginne derzeit alle meine db-Anforderungen in jeder Klasse mit:

 DataClassesDataContext db = new DataClassesDataContext()

Dann mache ich eine beliebige Linq-Anfrage innerhalb der Methode und fahre mit der Hauptanwendungslogik fort.

Nun zu zwei interessanten Fragen:

1) Ich glaube, ich habe Leute gesehen, die die DB-Nutzung in "using" einpacken. Wie zum Beispiel:

using (DataClassesDataContext db = new DataClassesDataContext())
{
    ...
}

Wenn dies korrekt ist, bedeutet dies dann nicht, dass meine Klasse keine Mitgliedsvariable "db" mehr verwenden kann, sondern dass diese db-Anfragen in jedem Funktionsaufruf erfolgen müssen? Und was genau würde passieren, wenn ich in den Aufrufen kein "using" verwende?

2) Wenn ich meine Anwendung mit aktiviertem SQL Profiler ausführe, sehe ich viele Verbindungen, die geöffnet und geschlossen werden. Bedeutet dies, dass jeder DataClassesDataContext-Aufruf eine separate Verbindung herstellt? Das scheint ineffizient zu sein. Ist es also der richtige Weg, das DataClassesDataContext-Objekt zu einem statischen Objekt innerhalb jeder verwendeten Klasse zu machen?

1voto

jason Punkte 227577

Im Allgemeinen sollten Sie eine DataContext pro Datenbankkonversation. Nur Sie können entscheiden, was genau eine Konversation ist, aber in der Regel handelt es sich um eine vollständige Anfrage (z. B. Abruf der Wunschliste des Benutzers oder Abruf der abgeschlossenen Bestellungen des Benutzers), die Sie sich als "Arbeitseinheit" vorstellen können.

Normalerweise läuft es in etwa so ab:

WishList wishlist;
using(var context = new DataContext(connectionString)) {
    var service = new UserWishListService(context);
    wishlist = service.GetUserWishList();
}

Und was genau würde passieren, wenn ich nicht using innerhalb der Anrufe?

En DataContext nicht ordnungsgemäß entsorgt werden (es sei denn, Sie haben sie in ein try-catch-finally verwenden, aber im Allgemeinen sollten Sie nur using ).

Bedeutet dies, dass jeder DataClassesDataContext Anruf eine separate Verbindung herstellt?

Nicht ganz. Ihre Anwendung profitiert von den integrierten Funktionen des SQL Server ADO.NET-Anbieters Pooling von Verbindungen . Machen Sie sich darüber keine Gedanken, überlassen Sie dies dem Anbieter.

Das scheint ineffizient zu sein, ist also der richtige Weg, um die DataClassesDataContext Objekt a static innerhalb jeder Klasse verwendet werden?

Auf keinen Fall. DataContext s sind nicht thread-sicher (tatsächlich sind sie thread-unsicher), und das hat "there be dragons" ganz groß geschrieben. Außerdem ist selbst ein Single-Thread-Kontext, ein static DataContext ist eine schlechte Wahl, weil die DataContext unterhält einen Zwischenspeicher (zum Zwecke der Objektverfolgung) für alle Entitäten, die es aus der Datenbank gezogen hat. Mit der Zeit wird der Speicherverbrauch gigantisch werden.

1voto

Remus Rusanu Punkte 280155

Da Sie das asp.net-Tag hinzugefügt haben, bedeutet dies, dass Sie den Kontext innerhalb eines HTTP-Aufrufs verwenden. Ein statischer Memberkontext ist in asp.net unbrauchbar, da Sie den Zugriff darauf synchronisieren müssen, und da Ihr Datenkontext von jede Aufruf kann immer nur eine HTTP-Antwort ausgeliefert werden, ein Skalierbarkeitsfiasko epischen Ausmaßes.

Aus diesem Grund werden Datenkontexte "on-the-go" erstellt und entsorgt. In der Tat, die Klassenspezifikationen wird dieses Verwendungsmuster deutlich hervorgehoben:

Im Allgemeinen ist eine DataContext-Instanz für eine "Arbeitseinheit" ausgelegt Arbeitseinheit", wie auch immer Ihre Anwendung diesen Begriff definiert. Ein DataContext ist leichtgewichtig und ist nicht teuer in der erstellen. Eine typische LINQ to SQL Anwendung erstellt DataContext Instanzen im Methodenbereich oder als Mitglied von kurzlebigen Klassen, die einen logischen Satz von verwandten Datenbank-Operationen darstellen.

Für ASP.Net ist ein sinnvoller "Unit-of-Work"-Kontext der HTTP-Aufruf selbst. Eine längere Diskussion zu diesem Thema finden Sie unter Linq to SQL DataContext Lifetime Management .

Die Frage des Öffnens und Schließens von Verbindungen ist nicht von Belang. Normalerweise werden die Verbindungen gepoolt und die "Öffnung" ist nichts anderes als eine Wiederverwendung einer Verbindung aus dem Pool. Wenn Sie eine schwergewichtige Verbindung öffnen (vollwertige Anmeldung), verwenden Sie das Pooling falsch. Vergleich von Anmeldungen/Sek. y Verbindungsrückstellungen/sec Die Zähler werden schnell zeigen, ob dies tatsächlich der Fall ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X