基于身份声明的动态数据库连接字符串

时间:2017-11-21 22:16:37

标签: c# asp.net-mvc connection-string claims-based-identity

我在我的网络应用程序中添加了一些“租约” 我的Web应用程序使用2个数据库

  • 身份数据库
  • 一个特定于租户的数据库(所有相同的架构)

应用程序是使用第二个一个静态连接字符串构建的 数据库中。

我使用静态连接字符串工作的AppointmentsControllers:

public class AppointmentsController : Controller
{
    private appDbContext _context;

    public AppointmentsController()
    {
        _context = new appDbContext();
    }

    protected override void Dispose(bool disposing)
    {
        _context.Dispose();
    }

    // Index
    public ViewResult Index()
    {
        var query = from c in _context.Appointments
                    orderby c.RegistrationDate
                    select c;
        //etc...
    }
}

要添加一些多租户,我已经更改了DbContext部分,以便我可以修改数据库连接。 这部分工作正常,它允许我更改数据库名称:

public class appDbContext : DbContext
{
    public DbSet<Appointments> Appointments { get; set; }

    public appDbContext(string database)
        : base(@"Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=" + database + ";Integrated Security=True")
    {
    }
}

从这里我迷路了。似乎可能从我的AppointmentsController构造函数连接正确的数据库,如下所示:

public class AppointmentsController : Controller
{
    private appDbContext _context;

    public AppointmentsController()
    {
        _context = new appDbContext("DbName");
    }

但我无法从身份中检索我的声明并将其从此构造函数传递给构造函数,如下所示:

public class AppointmentsController : Controller
{
    private appDbContext _context;

    public AppointmentsController()
    {
        var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
        var currentUser = manager.FindById(User.Identity.GetUserId());
        _context = new appDbContext(currentUser.DBName);
    }           

所以我的最佳方法就是完成这项工作,但我认为这不是很干净/顺利:

public class AppointmentsController : Controller
{
    private appDbContext _context;

    public AppointmentsController()
    {
        _context = new appDbContext("");
    }

    protected override void Dispose(bool disposing)
    {
        _context.Dispose();
    }

    private string GetCurrentUserDatabaseName()
    {
        var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
        var currentUser = manager.FindById(User.Identity.GetUserId());

        return currentUser.DBName;
    }

    // Index
    public ViewResult Index()
    {
        _context = new appDbContext(GetCurrentUserDatabaseName());

        var query = from c in _context.Appointments
                    orderby c.RegistrationDate
                    select c;
     //etc
    }
}

我觉得我很接近,但我怎样才能改进这段代码?

1 个答案:

答案 0 :(得分:0)

Web.Config中添加两个连接字符串:

  <connectionStrings>
    <add name="DefaultConnection" connectionString=Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=DefaultDataBase;Integrated Security=True" providerName="System.Data.SqlClient" />     
  </connectionStrings>

然后

    public class ApplicationDbContext : DbContext //change DbContext name appDbContext by ApplicationDbContext
        {
            public DbSet<Appointments> Appointments { get; set; }

            public ApplicationDbContext(database=""): base("name=DefaultConnection")
            {
          //And/Or you can do this programmatically.
          if(!string.IsNullOrWhiteSpace(database)
             {
               this.Database.Connection.ConnectionString = @"Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=" + database + ";Integrated Security=True";
 //OR Database.Connection.ChangeDatabase(database);
             }
            // More Stuff.....
            }
        }

使用:

public class AppointmentsController : Controller
{
    private ApplicationDbContext _context;

    public AppointmentsController()
    {
        _context = new ApplicationDbContext("DataBasConnection");
    }
}

OR

当您需要DefultDatabase时

public class AppointmentsController : Controller
{
    private ApplicationDbContext _context;

    public AppointmentsController()
    {
        _context = new ApplicationDbContext();
    }
}