10

MVC4EF5を使用してマルチテナント Web アプリケーションを開発しています。以前、DbContext のフィルタリングに関して次の質問をしました: Is it bad practice to filter ID within the repository pattern .

どうやら、私のアプローチは健全でしたが、その単一のリポジトリですべてのフィルタリングを処理するのではなく、「[my] 通常のリポジトリにフィードするリポジトリまたは DBContextWrapper クラス」を使用して、テナント レベルに既にフィルタリングされたコンテキストを提供することが提案されました。

残念ながら私は MVC の専門家ではないので、できる限りこれを実装し始めましたが、他のマルチテナント アプリケーションの EF でのフィルタリングを調査したところ、非常によく似たケース の Multi-tenancy web application withfiltered dbContextという質問が見つかりましたが、完全に失敗しました。その答えを理解すること。

私のアプリケーションでは、CompanyID は User クラスのプロパティであるため、認証されたユーザーから直接取得する必要があります。例えば:

int CompanyID = db.Users.Single(u => u.Email == User.Identity.Name).CompanyID;

私の現在のアプローチは機能しているように見えますが、同じ種類のことを行うことについて他の質問で見たことに基づいて、間違った方法で行ったり、非効率的に行ったりしたと確信しています。別の質問では、エンティティ フレームワーク リフレクションを使用した単純なマルチ テナント Web アプリケーションのソリューションがこれを行うために使用されますが、それが私の場合に適用されるかどうか、または使用方法さえもわかりません。

誰かがこれについての最善の方法と、さまざまな方法の長所/短所を説明できれば、非常に感謝しています。ありがとう :)

私の現在の実装は次のとおりです。

DB

  • 1 つのデータベース、複数のテナント。
  • すべてのテーブルに CompanyID フィールドがあるわけではありませんが、すべてのテーブルが何らかの方法で Company テーブルにリンクされています。

TestController.cs

public class TestController : Controller
{
    private BookingSystemEntities db = new BookingSystemEntities();
    public ActionResult Index()
    {
        var user = db.Users.Single(u => u.Email == User.Identity.Name);
        IBookingSystemRepository rep = new BookingSystemRepository(db, user);            
        return View(rep.GetAppointments(false));
    }

}

BookingSystemRepository.cs

public class BookingSystemRepository : IBookingSystemRepository
{
    private CompanyBookingSystemRepository db;

    public BookingSystemRepository(BookingSystemEntities context, User user)
    {
        this.db = new CompanyBookingSystemRepository(context, user);
    }

    public IEnumerable<Appointment> GetAppointments()
    { return GetAppointments(false); }

    public IEnumerable<Appointment> GetAppointments(bool includeDeleted)
    {
        return includeDeleted
            ? db.Appointments
            : db.Appointments.Where(a => a.Deleted.HasValue);
    }

    public IEnumerable<Client> GetClients()
    { return GetClients(false); }

    public IEnumerable<Client> GetClients(bool includeDeleted)
    {
        return includeDeleted
            ? db.Clients
            : db.Clients.Where(c => c.Deleted.HasValue);
    }

    public void Save()
    {
        db.SaveChanges();
    }

    public void Dispose()
    {
        if (db != null)
            db.Dispose();
    }
}

CompanyBookingSystemRepository.cs

public class CompanyBookingSystemRepository
{
    private BookingSystemEntities db;
    private User User;
    public IEnumerable<Appointment> Appointments { get { return db.Appointments.Where(a => a.User.CompanyID == User.CompanyID).AsEnumerable<Appointment>(); } }
    public IEnumerable<Client> Clients { get { return db.Clients.Where(a => a.CompanyID == User.CompanyID).AsEnumerable<Client>(); } }

    public CompanyBookingSystemRepository(BookingSystemEntities context, User user)
    {
        db = context;
        this.User = user;
    }

    public void SaveChanges()
    {
        db.SaveChanges();
    }

    public void Dispose()
    {
        if (db != null)
            db.Dispose();
    }
}
4

1 に答える 1