Filtern von DbContext in einer mandantenfähigen Anwendung mithilfe von Entity Framework mit MVC4

9

Ich entwickle eine mandantenfähige Webanwendung mit MVC4 und EF5 . Ich habe zuvor diese Frage bezüglich der Filterung meines DbContext gestellt: Ist es eine schlechte Übung, nach ID im Repository-Muster zu filtern .

Offensichtlich war mein Ansatz stichhaltig, aber es wurde vorgeschlagen, dass ich nicht den gesamten Filter in diesem einzigen Repository behandle, sondern einen Kontext, der bereits auf Tenant-Ebene mit 'einem Repository oder DBContextWrapper gefiltert ist Klasse, die Ihr [my] normales Repository füttern würde .

Leider bin ich kein MVC-Experte, also habe ich angefangen, dies so gut wie möglich zu implementieren, aber nachdem ich die Filterung in EF für andere mandantenfähige Anwendungen untersucht hatte, fand ich eine Frage für einen sehr ähnlichen Fall Multi-Tenancy-Webanwendung mit gefiltertem dbContext , obwohl die Antwort darauf nicht vollständig verstanden wurde.

In meiner Anwendung ist die CompanyID eine Eigenschaft der Benutzerklasse und sollte daher direkt vom authentifizierten Benutzer übernommen werden. ZB:

%Vor%

Mein derzeitiger Ansatz scheint zu funktionieren, aber ich bin mir ziemlich sicher, dass ich es in die falsche Richtung gegangen bin und / oder es ineffizient gemacht habe, basierend auf dem, was ich in anderen Fragen über die gleiche Art von Dingen gesehen habe. In einer anderen Frage Lösungen für eine einfache Multi-Tenant-Web-Anwendung mit Entity-Framework Reflexion wird verwendet, um dies zu tun, aber ich bin nicht in der Lage um herauszufinden, ob es in meinem Fall zutreffen würde, oder wie man es überhaupt benutzt.

Ich wäre sehr dankbar, wenn irgendjemand den besten Weg erklären könnte, dies zu tun, und die Vor- und Nachteile unterschiedlicher Wege. Danke:)

Meine aktuelle Implementierung ist wie folgt:

DB

  • Eine Datenbank, mehrere Mandanten.
  • Alle Tabellen sind auf die eine oder andere Weise mit der Tabelle "Firma" verknüpft, obwohl nicht alle ein Firmen-ID-Feld haben.

TestController.cs

%Vor%

BookingSystemRepository.cs

%Vor%

CompanyBookingSystemRepository.cs

%Vor%     
Matthew Hudson 19.06.2013, 11:34
quelle

1 Antwort

1

Ich mag Ihre Vorgehensweise besser als einige der anderen Beispiele, die Sie zur Verfügung gestellt haben. Die Filterung basierend auf dem angemeldeten Benutzer sollte der effektivste Weg sein, um sicherzustellen, dass Sie Ihre Daten entsprechend filtern, vorausgesetzt, dass jeder Mandanten von derselben Codebasis und Domäne ausgeführt wird. (Wenn nicht, könnten Sie diese auch zum Filtern verwenden.)

Wenn Sie Bedenken hinsichtlich der Datenbankleistung mit Filtertabellen haben, die keine CompanyID haben, können Sie Ihre Datenbank absichtlich denormalisieren, um dieses Feld in diese Tabellen aufzunehmen.

Der von Ihnen angeführte Reflektionsansatz scheint, obwohl er elegant ist, übermäßig kompliziert zu sein und viel mehr Aufwand als die CompanyID in Ihrem db-Aufruf einzuschließen (besonders da der db-Aufruf in beiden Fällen stattfindet).

BEARBEITEN (nach Kommentar):

Was den Rest angeht, haben Sie anscheinend eine Menge überflüssigen Code geschrieben, der nicht wirklich notwendig ist (zumindest nicht in dem oben genannten Beispiel). Ich verstehe nicht unbedingt, warum Sie zwischen einem BookingSystemRepository und einem CompanyBookingSystemRepository unterscheiden, denn von Ihrem Code scheint es, als ob der erstere besteht, Anrufe nur an letztere weiterzuleiten, die Ergebnisse nur mit der UserID filtern (gibt es jemals eine Situation, in der Sie würden diese Ergebnisse nicht filtern?).

Sie können diese beiden Klassen (und das Problem, das Sie in Ihrem Kommentar angeben) vollständig eliminieren, indem Sie einfach Ihre Methode wie folgt ändern:

%Vor%

Von dort aus sollten Sie, wenn Sie sich Sorgen um die Leistung machen, wirklich all Ihre Filterung in der Datenbank vornehmen und dann nur diese Prozeduren aufrufen, um Ihre Daten zurückzugeben.

    
Chris Searles 19.06.2013 13:06
quelle