GOOGLE ADS

Donnerstag, 14. April 2022

Wann sollte ich einen neuen DbContext() erstellen?

Ich benutze derzeit ein DbContextähnliches:

namespace Models
{
public class ContextDB: DbContext
{

public DbSet<User> Users { get; set; }
public DbSet<UserRole> UserRoles { get; set; }
public ContextDB()
{

}
}
}

Ich verwende dann die folgende Zeile oben auf ALLEN meinen Controllern, die Zugriff auf die Datenbank benötigen. Ich verwende es auch in meiner UserRepository-Klasse, die alle Methoden in Bezug auf den Benutzer enthält (z. B. den aktiven Benutzer abrufen, überprüfen, welche Rollen er hat usw.):

ContextDB _db = new ContextDB();

In Anbetracht dessen kann es vorkommen, dass ein Besucher mehrere DbContexts aktiv haben kann, beispielsweise wenn er einen Controller besucht, der das UserRepository verwendet, was möglicherweise nicht die beste Idee ist.

Wann sollte ich einen neuen DbContext erstellen? Sollte ich alternativ einen globalen Kontext haben, der herumgereicht und überall wiederverwendet wird? Würde das zu einem Leistungseinbruch führen? Vorschläge für alternative Möglichkeiten, dies zu tun, sind ebenfalls willkommen.


Lösung des Problems

Ich verwende einen Basiscontroller, der eine DataBaseEigenschaft verfügbar macht, auf die abgeleitete Controller zugreifen können.

public abstract class BaseController: Controller
{
public BaseController()
{
Database = new DatabaseContext();
}
protected DatabaseContext Database { get; set; }
protected override void Dispose(bool disposing)
{
Database.Dispose();
base.Dispose(disposing);
}
}

Alle Controller in meiner Anwendung stammen von BaseControllerund werden wie folgt verwendet:

public class UserController: BaseController
{
[HttpGet]
public ActionResult Index()
{
return View(Database.Users.OrderBy(p => p.Name).ToList());
}
}

Nun zur Beantwortung Ihrer Fragen:

Wann sollte ich einen neuen DbContext erstellen / sollte ich einen globalen Kontext haben, den ich herumreiche?

Der Kontext sollte pro Anfrage erstellt werden. Erstellen Sie den Kontext, tun Sie, was Sie damit tun müssen, und entfernen Sie ihn dann. Mit der von mir verwendeten Basisklassenlösung müssen Sie sich nur um die Verwendung des Kontexts kümmern.

Versuchen Sie nicht, einen globalen Kontext zu haben (so funktionieren Webanwendungen nicht).

Kann ich einen globalen Kontext haben, den ich überall wiederverwende?

Nein, wenn Sie einen Kontext um ihn herum halten, werden alle Aktualisierungen, Hinzufügungen, Löschungen usw. verfolgt, und dies wird Ihre Anwendung verlangsamen und kann sogar dazu führen, dass einige ziemlich subtile Fehler in Ihrer Anwendung auftreten.

Sie sollten sich wahrscheinlich dafür entscheiden, entweder Ihr Repository oder Ihren Kontext für Ihren Controller verfügbar zu machen, aber nicht beides. Der Zugriff auf zwei Kontexte von derselben Methode führt zu Fehlern, wenn beide unterschiedliche Vorstellungen vom aktuellen Zustand der Anwendung haben.

Persönlich ziehe ich es vor, DbContextdirekt zu exponieren, da die meisten Repository-Beispiele, die ich gesehen habe, DbContextsowieso einfach als dünne Hüllen herumlaufen.

Führt dies zu Leistungseinbußen?

Das erste Mal, wenn a DbContexterstellt wird, ist ziemlich teuer, aber sobald dies geschehen ist, werden viele Informationen zwischengespeichert, so dass nachfolgende Instanziierungen viel schneller sind. Es ist wahrscheinlicher, dass Sie Leistungsprobleme sehen, wenn Sie einen Kontext aufrechterhalten, als wenn Sie jedes Mal einen Kontext instanziieren, wenn Sie Zugriff auf Ihre Datenbank benötigen.

Wie machen das alle anderen?

Es hängt davon ab, ob.

Einige Leute ziehen es vor, ein Abhängigkeitsinjektions-Framework zu verwenden, um eine konkrete Instanz ihres Kontexts an ihren Controller zu übergeben, wenn sie erstellt wird. Beide Optionen sind in Ordnung. Mine eignet sich eher für eine kleine Anwendung, bei der Sie wissen, dass sich die verwendete spezifische Datenbank nicht ändern wird.

Einige mögen argumentieren, dass Sie dies nicht wissen können und deshalb die Abhängigkeitsinjektionsmethode besser ist, da sie Ihre Anwendung widerstandsfähiger gegen Änderungen macht. Meine Meinung dazu ist, dass es sich wahrscheinlich nicht ändern wird (SQL Server und Entity Framework sind kaum obskur) und dass ich meine Zeit am besten damit verbringe, den Code zu schreiben, der für meine Anwendung spezifisch ist.

Keine Kommentare:

Kommentar veröffentlichen

Warum werden SCHED_FIFO-Threads derselben physischen CPU zugewiesen, obwohl CPUs im Leerlauf verfügbar sind?

Lösung des Problems Wenn ich das richtig verstehe, versuchen Sie, SCHED_FIFO mit aktiviertem Hyperthreading ("HT") zu verwenden, ...