Ich muss einen Entity Framework-Datenkontext für Plugins von Drittanbietern verfügbar machen. Der Zweck besteht darin, diesen Plugins zu erlauben, nur Daten abzurufen und keine Einfügungen, Aktualisierungen oder Löschungen oder andere Befehle zur Datenbankänderung auszugeben. Wie kann ich also einen Datenkontext oder eine Entität schreibgeschützt machen?
112
DbContext
, gib ihnen eineIQueryable
oder mehrere.Antworten:
Neben der Verbindung mit einem schreibgeschützten Benutzer können Sie noch einige andere Dinge mit Ihrem DbContext tun.
quelle
AsNoTracking()
Verwendung das verzögerte Laden unmöglich macht.public override Task<int> SaveChangesAsync()
.(context as IObjectContextAdapter).ObjectContext.SaveChanges()
wird immer noch funktionieren. Die beste Wahl ist, denDbContext(string nameOrConnectionString);
Contstructor mit einer Lese- / Schreib-Verbindungszeichenfolge für die Datenbankerstellung und einer anschließenden schreibgeschützten Verbindungszeichenfolge zu verwenden.Im Gegensatz zu der akzeptierten Antwort halte ich es für besser, die Komposition der Vererbung vorzuziehen . Dann müssten keine Methoden wie SaveChanges beibehalten werden, um eine Ausnahme auszulösen. Warum brauchen Sie überhaupt solche Methoden? Sie sollten eine Klasse so gestalten, dass sich ihr Verbraucher nicht täuschen lässt, wenn er sich die Liste der Methoden ansieht. Die öffentliche Schnittstelle sollte mit der tatsächlichen Absicht und dem eigentlichen Ziel der Klasse übereinstimmen, während in der akzeptierten Antwort mit SaveChanges nicht impliziert wird, dass der Kontext schreibgeschützt ist.
An Stellen, an denen ein schreibgeschützter Kontext erforderlich ist, z. B. auf der Leseseite des CQRS- Musters, verwende ich die folgende Implementierung. Es bietet seinem Verbraucher nichts anderes als Abfragefunktionen.
Mit ReadOnlyDataContext können Sie nur auf Abfragefunktionen von DbContext zugreifen. Angenommen, Sie haben eine Entität mit dem Namen Order. Dann würden Sie die ReadOnlyDataContext-Instanz wie folgt verwenden.
quelle
IDisposable
public IQueryable<TEntity> Get<TEntity>() where TEntity : class { return _dbContext.Query<TEntity>().AsNoTracking(); }