首页 > 解决方案 > 每个租户的 asp.net mvc 多租户数据库

问题描述

我正在为我们公司构建一个应用程序,该应用程序需要为每个客户提供单独的数据库。APP是供其他多家公司使用的,所以需要在用户登录时识别公司名称,使用户只能在公司db内操作。我已经设置好了,但问题是该应用程序无法同时处理 2 个不同的数据库。当来自两个不同公司的用户登录时,第一个用户的 db 将更改为第二个登录用户的 db!这当然是不能接受的。如何让应用程序同时使用 2 个数据库?

我有一个数据库,它收集所有应用程序用户及其公司名称以及每个公司的单独数据库。我也有一个标准的 asp 下面是我的代码:

帐户控制器中的登录类和数据库初始化程序

        [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        bool ifDemo = false;
        string demoPrefix = "demo.";
        if (model.Email.StartsWith(demoPrefix))
        {
            ifDemo = true;
            model.Email = model.Email.Substring(demoPrefix.Length);
        }

        SetDatabaseInitializerAndInitializeIt(ifDemo, model.Email);


        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, change to shouldLockout: true
        var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);

        switch (result)
        {
            case SignInStatus.Success:
                returnUrl = CheckFirstLogin(model.Email, returnUrl);
                        await OnSignInSuccess(model);
                //FormsAuthentication.SetAuthCookie(model.Email, false);
                return RedirectToLocal(returnUrl);
            case SignInStatus.LockedOut:
                return View("Lockout");
            case SignInStatus.RequiresVerification:
                return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
            case SignInStatus.Failure:
            default:
                ModelState.AddModelError("", "Invalid login attempt.");
                return View(model);
        }
    }

    public static void SetDatabaseInitializerAndInitializeIt(bool demoDB, string login)
    {
        Database.SetInitializer(new ApplicationUsersSeedData());
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<Facility.Data.FacilityEntities,
            Facility.Migrations.Configuration>());

        // Check current users company name and set the right database. 
        // To use demo version of database add "demo." prefix to the login email e.g: demo.testspamu79@gmail.com

        using (var domain = new Facility.Models.UserCommonDBContext())
        {
            domain.Database.Initialize(true);
        }

        UserCommonDBContext context = new Facility.Models.UserCommonDBContext();

        var companyName = context.CommonUser.Where(x => x.CommonUserEmail == login).FirstOrDefault().CommonUserCompanyName;
        if (demoDB)
            companyName = companyName + "Demo";

        using (var domain = new Facility.Data.FacilityEntities(companyName))
        {
            domain.Database.Initialize(true);
        }

    }

数据库上下文:

    public partial class FacilityEntities : DbContext
{
    public static string DbName;

    public FacilityEntities() : base(string.IsNullOrWhiteSpace(DbName) ? "Demo" : DbName)
    {
    }
    public FacilityEntities(string dbName) : base(dbName)
    {
        DbName = dbName;
    }

标签: asp.netasp.net-mvcentity-frameworkmulti-tenantdbcontext

解决方案


正如蒂尔森 T. 在评论中所说,我在会话中摆脱了静态和存储的数据库名称,现在它可以工作了!


推荐阅读