在ASP.NET Core上实施每个租户策略的数据库
不定時更新翻譯系列,此系列更新毫無時間規(guī)律,文筆菜翻譯菜求各位看官老爺們輕噴,如覺得我翻譯有問題請挪步原博客地址
本博文翻譯自:
http://gunnarpeipman.com/2017/08/database-per-tenant/
讓我們繼續(xù)使用ASP.NET Core web應(yīng)用程序中的多租戶,并關(guān)注每個租戶都有自己的數(shù)據(jù)庫的解決方案。它不僅僅是關(guān)于數(shù)據(jù)庫的——可以有更多的服務(wù),每個租戶都有自己的實(shí)例。它使這里提供的解決方案可以輕松地擴(kuò)展到除SQL Server或其他任何關(guān)系數(shù)據(jù)庫之外的其他服務(wù)。
以往的工作
在討論解決方案之前,我建議先瀏覽一下我以前的文章,內(nèi)容包括ASP.NET Core web應(yīng)用程序中的多租戶的一些方面:
-
Entity Framework Core 2.0 全局查詢過濾器
-
在 ASP.NET Core 中執(zhí)行租戶服務(wù)
注意!?本文中的代碼建立在上述文章的代碼之上。
將數(shù)據(jù)庫連接字符串移動到租戶配置
這里的問題是如何動態(tài)決定使用哪個連接字符串,以及如何使用web應(yīng)用程序配置未更改的方式使連接字符串可用。后者實(shí)際上是在我之前的多租戶文章中解決的在 ASP.NET Core 中執(zhí)行租戶服務(wù)我建議使用我此篇文章中提到的BlobStorageTenantProvider
與前一篇文章不同的是,當(dāng)租戶使用不同的數(shù)據(jù)庫時,在這些數(shù)據(jù)庫中不需要租戶id。不支持軟刪除的應(yīng)用程序可以在使用本文建議的解決方案時使用經(jīng)典的簡單數(shù)據(jù)上下文。
新的租戶類有一個額外的屬性-?DatabaseConnectionString,如這里所示。
public class Tenant{ ? ?public int Id { get; set; } ? ?public string Name { get; set; } ? ?public string Host { get; set; } ? ?public string DatabaseConnectionString { get; set; } }在Azure blob存儲中保存的租戶配置文件將是這樣的。
[{"Id": 2,"Name": "Local host","Host": "localhost:30172","DatabaseConnectionString": "<connection string 1>"},{"Id": 3,"Name": "Customer X","Host": "localhost:3331","DatabaseConnectionString": "<connection string 2>"},{"Id": 4,"Name": "Customer Y","Host": "localhost:33111","DatabaseConnectionString": "<connection string 3>"} ]
返回租戶而不是租戶ID
由于租戶可以定義更多的設(shè)置,所以開始處理租戶類而不是租戶ID。它將改變我的ITenantProvider接口和BlobStorageTenantProvider類。
public class BlobStorageTenantProvider : ITenantProvider{ ?
?private static IList<Tenant> _tenants; private Tenant _tenant; public BlobStorageTenantProvider(IHttpContextAccessor accessor, IConfiguration conf) ? ?{ ? ? ?
? ?if(_tenants == null){LoadTenants(conf["StorageConnectionString"], conf["TenantsContainerName"], conf["TenantsBlobName"]);} var host = accessor.HttpContext.Request.Host.Value; ? ? ?
? ??var tenant = _tenants.FirstOrDefault(t => t.Host.ToLower() == host.ToLower()); ? ? ? ?if(tenant != null){_tenant = tenant;}}
? ??private void LoadTenants(string connStr, string containerName, string blobName) ? ?{ ? ? ?
? ??var storageAccount = CloudStorageAccount.Parse(connStr); ? ?var blobClient = storageAccount.CreateCloudBlobClient(); ? ? ? ? ?? ?var container = blobClient.GetContainerReference(containerName); ? ? ? ?var blob = container.GetBlobReference(blobName);blob.FetchAttributesAsync().GetAwaiter().GetResult(); var fileBytes = new byte[blob.Properties.Length]; using (var stream = blob.OpenReadAsync().GetAwaiter().GetResult()) ? ? ? ?using (var textReader = new StreamReader(stream)) ? ? ?
? ??using (var reader = new JsonTextReader(textReader)){_tenants = JsonSerializer.Create().Deserialize<List<Tenant>>(reader);}}
? ??public Tenant GetTenant() ? ?{ ? ? ? ?return _tenant;} }
動態(tài)配置數(shù)據(jù)上下文
我想在這里,多租戶應(yīng)用程序不處理軟刪除。現(xiàn)在,為了使用正確的連接字符串,必須修改mult-tenant應(yīng)用程序的默認(rèn)數(shù)據(jù)上下文。
public class PlaylistContext : DbContext{ ?
?private readonly Tenant _tenant; public DbSet<Playlist> Playlists { get; set; } ?
?
??public DbSet<Song> Songs { get; set; } public PlaylistContext(DbContextOptions<PlaylistContext> options,ITenantProvider tenantProvider): base(options) ? ?{_tenant = tenantProvider.GetTenant();}
??protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) ? ?{optionsBuilder.UseSqlServer(_tenant.DatabaseConnectionString); base.OnConfiguring(optionsBuilder);}
??protected override void OnModelCreating(ModelBuilder modelBuilder) ? ?{modelBuilder.Entity<Playlist>().HasKey(e => e.Id);modelBuilder.Entity<Song>().HasKey(e => e.Id); base.OnModelCreating(modelBuilder);} }
在查看代碼時,很容易看出沒有多少代碼,但它會產(chǎn)生大膽靈活的模型,去支持不同的租戶策略。
結(jié)束
ASP.NET Core的依賴注入模型和Entity Framework Core的靈活性使得在ASP.NET Core web應(yīng)用程序中支持更復(fù)雜的場景變得非常容易。這篇博文關(guān)注的是多租戶的一個方面——如何支持每個租戶數(shù)據(jù)存儲策略的數(shù)據(jù)庫。如果需要的話,這個模型也可以擴(kuò)展到更多的設(shè)置。
相關(guān)文章:
-
從頭編寫 asp.net core 2.0 web api 基礎(chǔ)框架 (1)
-
Asp.Net Core 2.0 多角色權(quán)限認(rèn)證
-
調(diào)試 ASP.NET Core 2.0 源代碼
-
Entity Framework Core 2.0 全局查詢過濾器
-
在 ASP.NET Core 中執(zhí)行租戶服務(wù)
原文地址:?http://www.cnblogs.com/sheng-jie/p/7640163.html?
.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關(guān)注
總結(jié)
以上是生活随笔為你收集整理的在ASP.NET Core上实施每个租户策略的数据库的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一张图理清ASP.NET Core启动流
- 下一篇: 从头编写 asp.net core 2.