【发布时间】:2019-07-03 20:09:17
【问题描述】:
我们尝试这篇文章来实现基于数据库的租户提供程序 - https://www.codingame.com/playgrounds/5440/multi-tenant-asp-net-core-2---implementing-database-based-tenant-provider ...它有 2 个数据库上下文 ApplicationDbContext 和 MultiTenantDbContext。
我们设法为 ApplicationDbContext 做add-migration init and update-database 但我们可以不为 MultiTenantDbContext 做第二个...它一直说对象引用的问题未设置为对象的实例与`var host = accessor.HttpContext.Request.Host.Value有关;在下面的 /Models/Tenant.cs 上。
还有我的第二个问题,我不明白为什么这个 DatabaseTenantProvider 类会在 MultiTenantDbContext 的 add-migration init 中执行?!?!
有什么想法吗?
代码如下:
/Models/Tenant.cs:
using AthlosifyCore.Data;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace AthlosifyCore.Models
{
public class Tenant
{
[Key]
public Guid Id { get; set; }
public string Name { get; set; }
public string HostName { get; set; }
}
public interface ITenantProvider
{
Guid GetTenantId();
}
public class DatabaseTenantProvider : ITenantProvider
{
private Guid _tenantId;
public DatabaseTenantProvider(ApplicationDbContext context, IHttpContextAccessor accessor)
{
var host = accessor.HttpContext.Request.Host.Value;
context.AddSampleData();
// This is for real life cases
//_tenantId = context.Tenants.First(t => t.HostName == host).Id;
_tenantId = context.Tenants.First(t => t.HostName == "imaginary.example.com").Id;
}
public Guid GetTenantId()
{
return _tenantId;
}
}
}
/Data/ApplicationDbContext.cs:
using System;
using System.Collections.Generic;
using System.Text;
using AthlosifyCore.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace AthlosifyCore.Data
{
public class ApplicationDbContext : IdentityDbContext
{
private readonly IHttpContextAccessor _httpContextAccessor;
public DbSet<Tenant> Tenants { get; set; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options,
IHttpContextAccessor httpContextAccessor)
: base(options)
{
_httpContextAccessor = httpContextAccessor;
}
public void AddSampleData()
{
Tenants.Add(new Tenant
{
Id = MultitenantDbContext.Tenant1Id,
Name = "Imaginary corp.",
HostName = "imaginary.example.com"
});
Tenants.Add(new Tenant
{
Id = MultitenantDbContext.Tenant2Id,
Name = "The Very Big corp.",
HostName = "big.example.com"
});
SaveChanges();
}
}
}
/Data/MultitenantDbContext.cs:
using AthlosifyCore.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace AthlosifyCore.Data
{
public class MultitenantDbContext : DbContext
{
public static Guid Tenant1Id = Guid.Parse("51aab199-1482-4f0d-8ff1-5ca0e7bc525a");
public static Guid Tenant2Id = Guid.Parse("ae4e21fa-57cb-4733-b971-fdd14c4c667e");
public DbSet<Person> People { get; set; }
private ITenantProvider _tenantProvider;
public MultitenantDbContext(DbContextOptions<MultitenantDbContext> options,
ITenantProvider tenantProvider) : base(options)
{
_tenantProvider = tenantProvider;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Person>().HasQueryFilter(p => p.TenantId == _tenantProvider.GetTenantId());
}
public void AddSampleData()
{
People.Add(new Person
{
Id = Guid.Parse("79865406-e01b-422f-bd09-92e116a0664a"),
TenantId = Tenant1Id,
FirstName = "Gunnar",
LastName = "Peipman"
});
People.Add(new Person
{
Id = Guid.Parse("d5674750-7f6b-43b9-b91b-d27b7ac13572"),
TenantId = Tenant2Id,
FirstName = "John",
LastName = "Doe"
});
People.Add(new Person
{
Id = Guid.Parse("e41446f9-c779-4ff6-b3e5-752a3dad97bb"),
TenantId = Tenant1Id,
FirstName = "Mary",
LastName = "Jones"
});
SaveChanges();
}
}
}
【问题讨论】:
标签: c# asp.net-core .net-core