Arbeiten mit DbContext

Um mit Entity Framework Daten mithilfe von .NET-Objekten abzufragen, einzufügen, zu aktualisieren und zu löschen, müssen Sie zuerst ein Modell erstellen, das die Entitäten und Beziehungen, die in Ihrem Modell definiert sind, den Tabellen in einer Datenbank zuordnet.

Wenn Sie über ein Modell verfügen, ist System.Data.Entity.DbContext die primäre Klasse, mit der Ihre Anwendung interagiert (häufig als Kontextklasse bezeichnet). Sie können einen DbContext verwenden, der einem Modell zugeordnet ist, für Folgendes verwenden:

  • Schreiben und Ausführen von Abfragen
  • Materialisieren von Abfrageergebnissen als Entitätsobjekte
  • Nachverfolgen von Änderungen an diesen Objekten
  • Speichern von Objektänderungen in der Datenbank
  • Binden von Objekten im Arbeitsspeicher an Steuerelemente der Benutzeroberfläche

Auf dieser Seite finden Sie Leitfäden zum Verwalten der Kontextklasse.

Definieren einer abgeleiteten DbContext-Klasse

Die empfohlene Methode zum Arbeiten mit Kontexten besteht darin, eine Klasse zu definieren, die von DbContext abgeleitet wird und DbSet-Eigenschaften verfügbar macht, die Auflistungen der angegebenen Entitäten im Kontext darstellen. Wenn Sie mit dem EF Designer arbeiten, wird der Kontext für Sie generiert. Wenn Sie Code First anwenden, schreiben Sie den Kontext in der Regel selbst.

public class ProductContext : DbContext
{
    public DbSet<Category> Categories { get; set; }
    public DbSet<Product> Products { get; set; }
}

Wenn Sie über einen Kontext verfügen, können Sie Entitäten im Kontext über diese Eigenschaften abfragen, hinzufügen (mit den Methoden Add oder Attach) oder entfernen (mit Remove). Der Zugriff auf eine DbSet-Eigenschaft in einem Kontextobjekt stellt eine Startabfrage dar, die alle Entitäten des angegebenen Typs zurückgibt. Beachten Sie, dass der Zugriff auf eine Eigenschaft nicht die Abfrage ausführt. Eine Abfrage wird in folgenden Fällen ausgeführt:

  • Sie wird durch eine foreach (C#)-Anweisung oder eine For Each (Visual Basic)-Anweisung aufgezählt.
  • Sie wird durch einen Auflistungsvorgang, z. B. ToArray, ToDictionary oder ToList, enumeriert.
  • LINQ-Operatoren wie First oder Any werden im äußersten Teil der Abfrage angegeben.
  • Eine der folgenden Methoden wird aufgerufen: die Load-Erweiterungsmethode, DbEntityEntry.Reload, Database.ExecuteSqlCommand oder DbSet<T>.Find, wenn noch keine Entität mit dem angegebenen Schlüssel im Kontext geladen wurde.

Gültigkeitsdauer

Die Lebensdauer des Kontexts beginnt mit dem Erstellen der Instanz und endet, wenn die Instanz freigegeben oder an die Garbage Collection übergeben wird. Verwenden Sie using, wenn alle vom Kontext gesteuerten Ressourcen am Ende des Blocks freigegeben werden sollen. Wenn Sie using verwenden, erstellt der Compiler automatisch einen Try/Finally-Block und ruft „dispose“ im finally-Block auf.

public void UseProducts()
{
    using (var context = new ProductContext())
    {     
        // Perform data access using the context
    }
}

Für das Festlegen der Lebensdauer des Kontexts gelten die folgenden allgemeinen Richtlinien:

  • Wenn Sie mit Webanwendungen arbeiten, verwenden Sie eine Kontextinstanz pro Anforderung.
  • Wenn Sie mit Windows Presentation Foundation (WPF) oder Windows Forms arbeiten, verwenden Sie eine Kontextinstanz pro Formular. Auf diese Weise können Sie die vom Kontext bereitgestellten Nachverfolgungsfunktionen verwenden.
  • Wenn die Kontextinstanz durch einen Abhängigkeitseinfügecontainer erstellt wird, liegt es in der Regel in der Verantwortung des Containers, den Kontext freizugeben.
  • Wenn der Kontext im Anwendungscode erstellt wird, müssen Sie daran denken, den Kontext freizugeben, wenn er nicht mehr erforderlich ist.
  • Wenn Sie mit einem Objektkontext mit langer Ausführungszeit arbeiten, berücksichtigen Sie Folgendes:
    • Wenn Sie mehr Objekte und deren Verweise in den Arbeitsspeicher laden, kann sich der Arbeitsspeicherverbrauch des Kontexts schnell erhöhen. Dies kann zu Leistungseinbußen führen.
    • Der Kontext ist nicht threadsicher, daher sollte er nicht für mehrere Threads gemeinsam genutzt werden, die parallel damit arbeiten.
    • Wenn der Kontext aufgrund einer Ausnahme nicht wiederhergestellt werden kann, wird möglicherweise die gesamte Anwendung beendet.
    • Je größer der zeitliche Abstand zwischen der Abfrage der Daten und ihrer Aktualisierung, desto höher ist die Wahrscheinlichkeit, dass Parallelitätsprobleme auftreten.

Verbindungen

Standardmäßig werden Verbindungen mit der Datenbank vom Kontext verwaltet. Der Kontext öffnet und schließt Verbindungen nach Bedarf. Beispielsweise öffnet der Kontext die Verbindung, um eine Abfrage auszuführen, und schließt die Verbindung, wenn alle Resultsets verarbeitet wurden.

In bestimmten Fällen ist es erforderlich, den Zeitpunkt für das Öffnen und Schließen der Verbindung genauer zu steuern. Wenn Sie beispielsweise mit SQL Server Compact arbeiten, wird häufig empfohlen, eine separate offene Verbindung mit der Datenbank für die Lebensdauer der Anwendung aufrecht zu erhalten, um die Leistung zu verbessern. Mit der Connection-Eigenschaft können Sie diesen Vorgang manuell steuern.