asp.net MVC 6 动态数据库连接,用于 asp.net 身份



我有

控制器和 IAction结果如下

 public HomeController(
            UserManager<CustomerApplicationUser> userManager,
            SignInManager<CustomerApplicationUser> signInManager,
            IMemoryCache cache)
        {
            _userManager = userManager;
            _signInManager = signInManager;
            _cache = cache;
        }
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
var companyResult = new Company();
using (var GeneralCompanyContext = new GeneralCompanyContext())
{
companyResult = await GeneralCompanyContext.Company.FirstOrDefaultAsync(t => t.CompanyNumber == model.CompanyNumber);
}
using (var context = new CustomerContext(companyResult.ConnectionString))
{
var LoginResult = await _signInManager.PasswordSignInAsync(model.Email, model.Password, false, lockoutOnFailure: false);
}     
}

启动.cs

public void ConfigureServices(IServiceCollection services)
{
services.AddEntityFramework().AddSqlServer()
                    .AddDbContext<CustomerContext>()
                    .AddDbContext<GeneralCompanyContext>();
services.AddIdentity<CustomerApplicationUser, IdentityRole>().AddEntityFrameworkStores<CustomerContext>().AddDefaultTokenProviders();
services.AddIdentity<GeneralCompanyApplicationUser, IdentityRole>().AddEntityFrameworkStores<GeneralCompanyContext>().AddDefaultTokenProviders();

}

客户上下文类

CustomerContext : : IdentityDbContext<CustomerApplicationUser>
{
 private readonly string _ConnectionString;
     public CustomerContext()
     {
     _ConnectionString = Configuration["Data:DefaultConnection:MigrationConnectionString"]).ToString();
     }
     public CustomerContext(string ConnectionString)
     {
     _ConnectionString = ConnectionString;
     }
   protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(_ConnectionString);
        base.OnConfiguring(optionsBuilder);
    }
}

问题:

我有 2 个数据库上下文作为客户上下文和一般公司上下文。

CustomerContext有客户的数据库。

GeneralCompanyContext 包含所有客户的所有数据库连接字符串。

项目开始时间

服务业。AddEntityFramework()。AddSqlServer() 添加连接字符串来自

配置["数据:默认连接:迁移连接字符串"]

自动。因此,当我尝试登录索引Iactionresult时,signinmanager连接字符串始终显示配置["数据:默认连接:迁移连接字符串"]连接字符串。

如何从公司结果中为您设置连接字符串(asp.net 身份)

任何帮助将不胜感激。

谢谢。

问题是你尝试这样做的方式,很可能是行不通的。在输入登录方法之前,您必须提前知道公司编号,例如将其作为查询参数传递或使用子域来决定或其他方法。我最近不得不在Core 1.0 ASP.NET 做类似的事情。无法发布确切的代码,因为我最终围绕所有这些添加了基础结构代码,但我会尝试为您提供一些指导。

首先要知道的是,可以在上下文的 OnConfiguring 方法中替换CustomerContext连接字符串。这是最后的手段。

源。

public class CustomerDbContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        // optionsBuilder.UseSqlServer("Your connection string should injected here.");
    }
}

下一步是了解何时何地从 GeneralCompanyDatabase 获取连接字符串。这应该发生在相当于 MVC 5 中的 BeginRequest 中 - 在中间件中。

public class Tenant
{
    public string CustomerConnectionString { get; set; }
}
public class TenantMiddleware
{
    private readonly RequestDelegate next_;
    public TenantMiddleware(RequestDelegate next)
    {
        next_ = next;
    }
    public async Task Invoke(HttpContext httpContext, GeneralCompanyContext companyContext)
    {
        // You have to know your company number here somehow !!
        string customerConnectionString = await companyContext.Company.FirstOrDefaultAsync(t => t.CompanyNumber == 1).ConnectionString;
        Tenant tenant = new Tenant{ CustomerConnectionString = customerConnectionString };
        httpContext.Items["customerTenant"] = tenant;
        await next_(httpContext);
    }
}

现在,有了连接字符串,您必须使Tenant对象在 CustomerDbContext 中可注入

Startup.cs

services.AddScoped(prov => 
prov.GetService<IHttpContextAccessor>()?.HttpContext?.GetTenant());

GetTenant()是 HttpContext 的扩展方法。

public static Tenant GetTenant(this HttpContext context)
{
    object myObj;
    if (context.Items.TryGetValue("customerTenant", out myObj))
    {
        return myObj as Tenant;
    }
    return null;
}

现在,您的 CustomerDbContext 应如下所示:

public class CustomerDbContext : DbContext
{
    private Tenant tenant_;
    public CustomerDbContext(Tenant tenant)
    {
        tenant_ = tenant;       
    }
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(tenant.CustomerConnectionString);
    }
}

此时,SignInManager将使用正确的连接字符串。但是你开始的方式,我非常怀疑你会让它发挥作用。因为尝试替换连接字符串的位置,所有内容都已实例化和配置。同样,我只是手动键入代码片段来说明这个想法。此外,请考虑使用中间件中的IMemoryCache来缓存连接字符串,并避免对每个请求执行数据库调用。

相关内容

  • 没有找到相关文章

最新更新