【问题标题】:asp.net mvc multitenant database per tenant每个租户的 asp.net mvc 多租户数据库
【发布时间】:2018-06-27 16:50:14
【问题描述】:

我正在为我们的公司构建一个应用程序,该应用程序需要为每个客户提供单独的数据库。 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;
    }

【问题讨论】:

  • DbName 不应该是静态的,如果您不希望所有 FacilityEntities 实例具有相同的值。
  • @TiesonT。当我从“公共静态字符串 DbName”中删除“静态”时,我得到“公共 FacilityEntities() 中的非静态字段、方法或属性“成员”错误需要对象引用:base(string.IsNullOrWhiteSpace(DbName)? “演示”:DbName)'
  • 假设您只在“演示模式”下创建该 DbContext 的默认实例,只需使用字符串文字。
  • 如果您以后需要能够新建实例,请将数据库名称存储为声明。
  • @TiesonT。谢谢!在会话中摆脱了静态和存储的数据库名称。

标签: asp.net asp.net-mvc entity-framework multi-tenant dbcontext


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-03
    • 2020-09-04
    • 1970-01-01
    • 2017-09-16
    • 2012-01-21
    • 1970-01-01
    相关资源
    最近更新 更多