在多租户 ASP.NET Core 应用程序中创建基于架构的表的 EF Core 迁移

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

我正在尝试为多租户应用程序创建特定于租户的架构表。像下面这样

CREATE SCHEMA Tenant1;

CREATE TABLE Tenant1.Customers 
(
    CustomerId INT PRIMARY KEY,
    Name NVARCHAR(100),
    Email NVARCHAR(100),
    Phone NVARCHAR(15)
);

CREATE SCHEMA Tenant2;

CREATE TABLE Tenant2.Customers 
(
    CustomerId INT PRIMARY KEY,
    Name NVARCHAR(100),
    Email NVARCHAR(100),
    Phone NVARCHAR(15)
);

DbContext

public class ApplicationDbContext : DbContext
{
    private readonly string _schema;

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, string schema)
        : base(options)
    {
        _schema = schema ?? "default_schema";
    }

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
        _schema = "default_schema";
    }

    public virtual DbSet<Customer> Customers { get; set; }
    public virtual DbSet<Tenant> Tenants { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.HasDefaultSchema(_schema);
        base.OnModelCreating(modelBuilder);
    }
}

我有两个实体:

public class Customer
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string email { get; set; }
    public string Phone { get; set; }
    public DateTime CreatedOn { get; set; }
    public bool IsActive => true;
}

public class Tenant
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Schema { get; set; }
}

program.cs

builder.Services.AddDbContext<ApplicationDbContext>(optins =>
{
    optins.UseNpgsql(builder.Configuration.GetConnectionString("postgresConnection"));
});
builder.Services.AddScoped<TenantDbContextFactory>();

// Seed initial data
using (var scope = app.Services.CreateScope())
{
    var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
    await DataSeeder.SeedAsync(dbContext);
}

// Apply migrations for each tenant's schema
using (var scope = app.Services.CreateScope())
{
    var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
    var dbContextFactory = scope.ServiceProvider.GetRequiredService<TenantDbContextFactory>();
    var tenants = await dbContext.Tenants.ToListAsync();

    foreach (var tenant in tenants)
    {
        var tenantContext = dbContextFactory.CreateDbContext(tenant.Schema);
        await tenantContext.Database.MigrateAsync();
    }
}

但是,这些表仅在

DEFAULT_SCHEMA
中创建。未创建租户特定架构。

工厂方法:

public sealed class TenantDbContextFactory
{
    private readonly DbContextOptions<ApplicationDbContext> _options;

    public TenantDbContextFactory(DbContextOptions<ApplicationDbContext> options)
    {
        _options = options;
    }

    public ApplicationDbContext CreateDbContext(string schema)
    {
        return new ApplicationDbContext(_options, schema);
    }
}
c# asp.net-core entity-framework-core entity-framework-migrations
1个回答
0
投票

在租户循环中创建的 DbContext 并未像开始时那样注册:

builder.Services.AddDbContext<ApplicationDbContext>(optins =>
{
    optins.UseNpgsql(builder.Configuration.GetConnectionString("postgresConnection"));
});

我不确定动态创建数据库上下文是否有效。

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