我正在尝试为多租户应用程序创建特定于租户的架构表。像下面这样
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);
}
}
在租户循环中创建的 DbContext 并未像开始时那样注册:
builder.Services.AddDbContext<ApplicationDbContext>(optins =>
{
optins.UseNpgsql(builder.Configuration.GetConnectionString("postgresConnection"));
});
我不确定动态创建数据库上下文是否有效。