2011-01-16 11 views
3

Ich bin neu in Datenbanken und linq, so dass mein Problem als trivial betrachtet werden kann. Ich fange gerade alle meine db Anfragen in jeder Klasse mit:Effizienteren Datenbankzugriff

DataClassesDataContext db = new DataClassesDataContext() 

Dann gehe ich auf, was Linq Anfrage ich innerhalb des Verfahrens müssen machen und weitermachen mit dem Hauptanwendungslogik. Jetzt

, zwei interessante Anfragen:

1) Ich glaube, ich habe Leute gesehen, innerhalb db Nutzung Einwickeln ‚mit‘. Wie zum Beispiel:

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

Wenn dies richtig ist, dann bedeutet es nicht, dass meine Klasse nicht Mitglied ‚db‘ Variable mehr, sondern eher jene db-Anforderungen vorgenommen werden müssen in jedem Funktionsaufruf verwenden kann? Was würde genau passieren, wenn ich nicht innerhalb der Anrufe "benutze"?

2) Ausführen meiner App mit SQL Profiler aktiviert, sehe ich viele Verbindungen öffnen und schließen. Bedeutet dies, dass jeder DataClassesDataContext-Aufruf eine separate Verbindung herstellt? Es scheint ineffizient, also ist der richtige Weg, das DataClassesDataContext-Objekt tatsächlich zu einer statischen innerhalb jeder Klasse zu machen?

+0

Es gibt andere Frameworks wie Developer Express XPO, die Linq-Abfragen unterstützen. – abmv

Antwort

1

Im Allgemeinen sollten Sie eine DataContext pro Datenbankkonversation verwenden. Nur Sie können genau entscheiden, was eine Konversation ist, aber normalerweise ist es eine vollständige Anfrage (z. B. die Wunschliste des Benutzers holen oder die geschlossenen Aufträge des Benutzers abrufen), die Sie sich als "Arbeitseinheit" vorstellen.

Regel, was passiert, ist so etwas wie dieses:

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

Auch, was genau passiert, wenn ich using verwenden nicht innerhalb der Anrufe?

Die DataContext nicht ordnungsgemäß entsorgt werden (es sei denn, Sie in einem try-catch-finally gewickelt haben, aber in der Regel sollten Sie nur using verwenden).

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

Nicht ganz. Ihre Anwendung wird von dem integrierten connection pooling des SQL Server ADO.NET-Anbieters profitieren. Mach dir keine Sorgen, lass den Provider es für dich verwalten.

Es scheint ineffizient, so der richtige Weg ist, um die DataClassesDataContext Objekt ein static innerhalb jeder Klasse, um tatsächlich zu machen verwendet?

Absolut nicht. DataContext s sind nicht Thread-sicher (in der Tat sind sie Thread-unsicher) und dies hat "es gibt Drachen" überall geschrieben. Darüber hinaus ist sogar ein Kontext mit nur einem Thread, static DataContext, eine schlechte Wahl, da der DataContext einen Cache (für Objektverfolgungszwecke) aller Entitäten verwaltet, die er aus der Datenbank abgerufen hat. Im Laufe der Zeit wird der Speicherverbrauch ginormous.

1

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 nicht verwendbar.net, weil Sie den Zugriff darauf synchronisieren müssen, und da Ihr Datenkontext von alle Aufruf benötigt wird, können Sie nur eine HTTP-Antwort zu einem Zeitpunkt, ein Skalierbarkeit Fiasko von epischen Proportionen.

Aus diesem Grund werden Datenkontexte "on-the-go" erstellt und entsorgt. In der Tat, the class specifications ruft klar diese Verwendung Muster:

Im Allgemeinen wird eine Datacontext-Instanz ist ausgelegt für eine „Einheit von Arbeit“ dauern jedoch Ihre Anwendung definiert diesen Begriff. Ein DataContext ist leicht und ist nicht teuer zu erstellen. Eine typische LINQ to SQL Anwendung erstellt DataContext Instanzen im Methodenbereich oder als Mitglied von kurzlebigen Klassen, die eine logische Gruppe von verwandten Datenbankoperationen darstellen.

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

Das Problem der Verbindungen öffnen/schließen ist kein Problem. Normalerweise sind die Verbindungen gepoolt und die "Öffnung" ist nichts anderes als eine Wiederverwendung einer Verbindung aus dem Pool. Wenn Sie das Schwergewicht öffnen (vollständige Anmeldung), verwenden Sie das Pooling falsch. Vergleicht man Logins/sec und Connection Resets/sec Zähler werden schnell zeigen, ob das tatsächlich der Fall ist.

Verwandte Themen