在ASP.NET Core上实施每个租户策略的数据库
2017-10-08 16:04
405 查看
在ASP.NET Core上实施每个租户策略的数据库
不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址本博文翻译自:
http://gunnarpeipman.com/2017/08/database-per-tenant/
让我们继续使用ASP.NET Core web应用程序中的多租户,并关注每个租户都有自己的数据库的解决方案。它不仅仅是关于数据库的——可以有更多的服务,每个租户都有自己的实例。它使这里提供的解决方案可以轻松地扩展到除SQL Server或其他任何关系数据库之外的其他服务。
以往的工作
在讨论解决方案之前,我建议先浏览一下我以前的文章,内容包括ASP.NET Core web应用程序中的多租户的一些方面:Entity Framework Core 2.0 全局查询过滤器
在 ASP.NET Core 中执行租户服务
注意! 本文中的代码建立在上述文章的代码之上。
将数据库连接字符串移动到租户配置
这里的问题是如何动态决定使用哪个连接字符串,以及如何使用web应用程序配置未更改的方式使连接字符串可用。后者实际上是在我之前的多租户文章中解决的在 ASP.NET Core 中执行租户服务我建议使用我此篇文章中提到的BlobStorageTenantProvider与前一篇文章不同的是,当租户使用不同的数据库时,在这些数据库中不需要租户id。不支持软删除的应用程序可以在使用本文建议的解决方案时使用经典的简单数据上下文。
新的租户类有一个额外的属性-
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
由于租户可以定义更多的设置,所以开始处理租户类而不是租户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; } }
动态配置数据上下文
我想在这里,多租户应用程序不处理软删除。现在,为了使用正确的连接字符串,必须修改mult-tenant应用程序的默认数据上下文。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); } }
在查看代码时,很容易看出没有多少代码,但它会产生大胆灵活的模型,去支持不同的租户策略。
结束
ASP.NET Core的依赖注入模型和Entity Framework Core的灵活性使得在ASP.NET Core web应用程序中支持更复杂的场景变得非常容易。这篇博文关注的是多租户的一个方面——如何支持每个租户数据存储策略的数据库。如果需要的话,这个模型也可以扩展到更多的设置。欢迎转载,转载请注明翻译原文出处(本文章),原文出处(原博客地址),然后谢谢观看
如果觉得我的翻译对您有帮助,请点击推荐支持:)
相关文章推荐
- 在ASP.NET Core上实施每个租户策略的数据库
- ASP.NET Core 认证与授权[6]:授权策略是怎么执行的?
- 基于Citus和ASP.NET Core开发多租户应用
- ASP.NET Core 操作数据库提示“Microsoft.EntityFrameworkCore.DbUpdateException”
- asp.net core 使用EF7 Code First 创建数据库,同时使用命令创建数据库
- ASP.net core 2.0.0 中 asp.net identity 2.0.0 的基本使用(一)—修改数据库连接
- 基于Citus和ASP.NET Core开发多租户应用
- 【无私分享:ASP.NET CORE 项目实战(第五章)】Code First 创建数据库和数据表
- ASP.NET系统数据库一键式部署策略
- ASP.NET Core 认证与授权[6]:授权策略是怎么执行的?
- 学习ASP.NET Core Razor 编程系列十一——把新字段更新到数据库
- 【.NetCore学习】ASP.NET Core EF Core2.0 DB First现有数据库自动生成实体Context
- Asp.net core 通过Models 生成数据库的方法
- 创建第一个ASP.NET CORE程序 使用DBFirst模式连接数据库
- 在 ASP.NET Core 中执行租户服务
- asp.net core 2.0 web api基于JWT自定义策略授权
- Asp.net core 通过Models 生成数据库的方法
- 学习ASP.NET Core Razor 编程系列六——数据库初始化
- 在 ASP.NET Core 中执行租户服务
- 【ASP.NET Core】EF Core 模型与数据库的创建