2016-06-23 17 views
0

Ich versuche EF-Migrationen zu verwenden, um meine Datenbank zu erstellen, aber mein DbContext verursacht einen Fehler, wenn ich den Update-Datenbank-Befehl verwende.Abrufen von Benutzerinformationen in DbContext

Der DbContext, den ich implementiert habe, hat zwei Konstruktoren: der eine akzeptiert keine Argumente und der andere akzeptiert eine IUserContext-Schnittstelle. Die IUserContext-Schnittstelle gibt einen Benutzernamen als Zeichenfolge zurück. Der IUserContext wird in der SaveChanges() - Methode verwendet, um benutzerbezogene Prüffelder (z. B. CreatedBy, UpdatedBy) für alle meine Entitäten festzulegen. Abhängig von der Implementierung der IUserContext-Schnittstelle kann der Benutzername aus einem HttpContext (in einer MVC-App), WindowsIdentity (in einer Konsolen-App) usw. abgerufen werden.

Wenn ein Benutzer versucht, SaveChanges auf dem DbContext und der IUserContext ist nicht festgelegt, es löst eine Ausnahme aus. Grundsätzlich, Ich möchte keine Änderungen im DbContext gespeichert, wenn ein Benutzername nicht von der IUserContext-Schnittstelle zur Verfügung gestellt werden kann, um zu erfassen, wer die Änderungen vornimmt. Wenn der DbContext nur zum Abfragen verwendet wird, ist die Verwendung des No-Args-Konstruktors kein Problem, da IUserContext nur während SaveChanges verwendet wird.

Wenn ich versuche, den Befehl update-database zu verwenden, erhält DbMigrationsConfiguration eine Instanz des DbContext, der mit dem Konstruktor no-args instanziiert wurde. Daher wird eine Ausnahme ausgelöst, wenn versucht wird, die SaveChanges von DbContext nach der Seed() -Methode aufzurufen.

Frage: Wie kann ich einen IUserContext meiner DbContext geben, damit die Update-Datenbank Befehl nicht fehlschlagen und, was noch wichtiger ist, der Lage sein, die entsprechenden Unternehmen Felder auf den Namen des Benutzers, um die Änderungen Impfen? Gibt es eine Form von DI oder andere Anpassungen, die ich in der DbMigrationsConfiguration durchführen kann? Soll ich einfach eine IUserContext-Accessor-Methode zum DbContext hinzufügen, damit der IUserContext außerhalb des Konstruktors gesetzt werden kann?

Vielleicht sollte ich eine größere Frage stellen: Was das Beste ist (generischsten?) Art und Weise der für die Zwecke der Aufnahme Benutzerinformationen zu einem DbContext Weiterleitung, die Änderungen vorzunehmen ist?

Ich habe darüber nachgedacht, diese Logik in die Business-Schicht meiner Anwendung zu übertragen, aber es scheint so praktisch zu sein, sie in den SaveChanges des DbContext zu kapseln (umso mehr, wenn Change Tracking aktiviert ist).

Antwort

0

Wir haben eine ähnliche Situation, in der wir modifizierten Benutzer in SaveChanges() überschreiben. Am Ende haben wir einen BaseWrapper erstellt und IoC verwendet, um ihn zu füllen. Der zweite Teil erstellt eine MigrationsContextFactory, die Migrationen zum Erstellen des Kontexts verwenden. Diese Klasse befindet sich im selben Ordner wie unser ApplicationDbContext.

using System.Data.Entity.Infrastructure; 

namespace MyApp.Data 
{ 
    public class MigrationsContextFactory : IDbContextFactory<ApplicationDbContext> 
    { 
     public ApplicationDbContext Create() 
     { 
      return new ApplicationDbContext(new HttpContextBaseWrapper()); 
     } 
    } 
} 

public class HttpContextBaseWrapper : IHttpContextBaseWrapper 
{ 
    public string UserName 
    { 
     get 
     { 
      if (HttpContext.Current == null || HttpContext.Current.User == null) 
       return string.Empty; 
      return HttpContext.Current.User.Identity.Name; 
     } 
    } 
} 

https://marazt.wordpress.com/2015/01/09/entity-framework-dbcontext-idbcontextfactory-and-codefirst-migration-problem/

Verwandte Themen