0

我正在嘗試爲應用程序的多租戶設置找到最佳方式。我希望爲每個客戶提供一個TenantId的單一數據庫,其中包含所有租戶信息的單個表。例如, Db租戶表(TenantId,代碼,名稱等)多租戶一個數據庫一個模式ASP.NET MVC 5,實體框架6,

我有我的所有WebApi控制器和MVC控制器(WebApiBaseController和AppBaseController)的基礎控制器。我希望這兩個控制器根據當前用戶tenantId對結果進行歸檔。

應該用DbContext來照顧這個嗎?我確實想要在任何地方都有一個 users.Where(u => u.TenantId == CurrenctUser.TenantId)

我也看過this question,但我認爲這是一個不同的問題,他試圖解決。

對於這個項目,我使用: ASP.NET MVC 5 的WebAPI 2 實體框架6 AspNet.Identity

如何使用針對單個位置的tenantId篩選基於當前登錄的用戶實體?

UPDATE

public class ApplicationDbContext : IdentityDbContext<ApplicationUser> 
{ 
    public ApplicationDbContext() 
     : base("DefaultConnection", throwIfV1Schema: false) 
    { 
     Configuration.ProxyCreationEnabled = false; 
     Configuration.LazyLoadingEnabled = false; 
     Database.SetInitializer<ApplicationDbContext>(null);    
    } 

    public DbSet<Tenant> Tenants { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Configurations.Add(new TenantMap()); 
     modelBuilder.Configurations.Add(new ApplicationUserMap()); 

     // Create parameterized filter for all entities that match type ITenantEntity     
     modelBuilder.Filter(Infrastructure.Constants.TetantFilterName, (ITenantEntity b) => b.TenantId,() => string.Empty); 

     // By default the filter is disable to allow unauthenticated users to login 
     // FIX: This filter must be Enabled at the base controller for mvc and webapi 
     // basically, it will only get activated after the user logs in. See Base Controllers 
     modelBuilder.DisableFilterGlobally(Infrastructure.Constants.TetantFilterName); 
     base.OnModelCreating(modelBuilder); 
    } 

    public void EnableTenantFilter() 
    { 
     this.EnableFilter(Infrastructure.Constants.TetantFilterName);    
    } 

    public void DisableTenantFilter() 
    { 
     this.DisableFilter(Infrastructure.Constants.TetantFilterName); 
    } 

} 

[Authorize] 
public class WebApiBaseController : ApiController 
{ 

    ApplicationUser _currectUser; 

    public ApplicationUser CurrentUser 
    { 
     get 
     { 
      if (_currectUser == null) 
      { 
       AppDb.DisableTenantFilter(); 
       string currentUserId = User.Identity.GetUserId(); 
       _currectUser = AppDb.Users.FirstOrDefault(a => a.Id == currentUserId); 

       AppDb.EnableTenantFilter(); 
      } 


      return _currectUser; 

     } 
     set { _currectUser = value; } 
    } 

    public ApplicationDbContext AppDb 
    { 
     get; 
     private set; 
    } 

    public WebApiBaseController(ApplicationDbContext context) 
    { 
     AppDb = context; 

     if (User.Identity.IsAuthenticated) 
     {  
      AppDb.SetFilterGlobalParameterValue(Infrastructure.Constants.TetantFilterName, CurrentUser.TenantId); 
     }    
    } 

} 
+1

通過攔截添加過濾器可能是您最好的選擇:https://lostechies.com/jimmybogard/2014/05/29/missing-ef-feature-workarounds-filters/ –

+0

我曾嘗試過,但我遇到了問題當用戶未被認證時。它無法找到用戶,因爲我必須在創建過濾器時定義空租戶。到目前爲止,這就是我所擁有的。請參閱問題 –

+0

上的更新如果您不知道租戶是誰,因爲您不知道用戶是誰,您如何查詢未知租戶的數據?最重要的是,爲什麼? – JotaBe

回答

0

IMHO,我送用戶上下文(租戶ID,用戶ID)的數據存取,並設置租戶ID作爲用於每個查詢的過濾柱,這確保正確的數據訪問我。

如果您選擇基於控制器的過濾,如果您在稍後的時間點需要休息api會怎麼樣。在服務&/DAL中處理安全系統是我找到的最佳解決方案。

相關問題