具有ASP.NET Core 3.0和EF Core的多租户应用程序

问题描述 投票:0回答:1

我正在开发一个基于多租户的应用程序,它将为每个学校/租户提供一个单独的数据库。每个方案将彼此相同。想法是使用.NET Core 3和EF Core拥有一个数据库上下文。

例如,客户端导航到school1.gov.uk,然后使用存储在appsettings.json中'school1'下的连接字符串实例化SchoolContext。

当前,我必须对添加的每个新上下文运行添加迁移。任何人都可以提出一种解决方案来在单个上下文(即SchoolContext)下运行一次迁移吗?

主要上下文

public class SchoolContext : DbContext
{     protected readonly IConfiguration _configuration;
      private readonly IHttpContextAccessor _httpContextAccessor;

    public DbSet<Student> Students { get; set; }
    public DbSet<Course> Courses { get; set; }

    public SchoolContext(IConfiguration configuration, IHttpContextAccessor httpContextAccessor) 
    {
        _configuration = configuration;
        _httpContextAccessor = httpContextAccessor;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
            var subdomain = _httpContextAccessor.HttpContext.Request.Host.Host;
            var connectionString = _configuration.GetConnectionString(subdomain);
            optionsBuilder.UseSqlServer(connectionString);
    }

} 

租户上下文1

public class School1Context : SchoolContext
{
    public Schoo1Context()
    {

    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
         var connectionString = _configuration.GetConnectionString("School1");
         optionsBuilder.UseSqlServer(connectionString);
    }

} 

Tenant上下文2

public class School2Context : SchoolContext
{
    public School2Context()
    {

    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
         var connectionString = _configuration.GetConnectionString("School2");
         optionsBuilder.UseSqlServer(connectionString);
    }

} 

Program.cs

         using (var scope = host.Services.CreateScope())
         {
             var school1Context = scope.ServiceProvider.GetService<School1Context>();
             school1Context.Database.Migrate();
             var school2Context = scope.ServiceProvider.GetService<School2Context>();
             school2Context.Database.Migrate();
         }

Appsettings.json

"ConnectionStrings": {
    "School1": "Persist Security Info=true;Data Source=.\\SQLEXPRESS;Initial Catalog=School1;User ID=;Password=;",
    "School2": "Persist Security Info=true;Data Source=.\\SQLEXPRESS;Initial Catalog=School2;User ID=;Password=;",

   }
.net entity-framework asp.net-core .net-core entity-framework-4
1个回答
0
投票

我在您的代码中看到的最大问题是您应该具有1个上下文(因为它们都是相同的架构,对吗?)。如果它们具有不同的架构,那么您将需要不同的上下文。

该单个上下文应使用学校的特定连接字符串实例化。

这样,您可以针对1个上下文(不是多个)添加迁移。

您大多在那儿,只需删除School1Context和School2Context,因为在这里:

SchoolContext.cs

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
   var subdomain = _httpContextAccessor.HttpContext.Request.Host.Host;
   var connectionString = _configuration.GetConnectionString(subdomain); // <--- this is tenanted already
   optionsBuilder.UseSqlServer(connectionString);
}

您已经获取了连接字符串并连接到另一个数据库。

您在原始问题中陈述了答案:

想法是使用.NET Core 3和EF来拥有一个数据库上下文核心。

轻微插入到我每天都喜欢和使用的框架中:ServiceStack具有内置的多租户-ServiceStack Multitenancy

© www.soinside.com 2019 - 2024. All rights reserved.