如何在运行时更改dbcontext连接字符串中的数据库名称 [英] How to change database name in dbcontext connection string at runtime

查看:184
本文介绍了如何在运行时更改dbcontext连接字符串中的数据库名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Asp.Net MVC应用程序设置如下. 解决方案中有4个项目.

My Asp.Net MVC application is setup as follows. There are 4 projects in solution.

  • ge.Web
  • ge.BLL
  • ge.Core
  • ge.Entities

控制器初始化ge.Core中存在的存储库对象

Controller in ge.Web initializes a repository object present in ge.Core

 public class MapsController : Controller
 {
      private AssessmentRepository repAssessments = new AssessmentRepository("name=GEContext", schoolCode);

      public ActionResult DisplaySearchResults()
      {
        .....
      }
  }

评估资料库

  public class AssessmentRepository : Repository<Assessment>, IAssessmentRepository
{
    public AssessmentRepository(string connString, string schoolCode)
        :base(connString, schoolCode)
    { }
 }

存储库

  public class Repository<TEntity> : IRepository<TEntity> where TEntity:class
{
    protected readonly GEContext context;


    public Repository(string connString, string schoolCode) {
        context = new GEContext(connString);
    }
 }

GEContext

 public class GEContext : DbContext
 {
    public GEContext(string connString):base(connString) 
    {
        this.Configuration.LazyLoadingEnabled = false;
        Database.SetInitializer(new MySqlInitializer());
    }
  }

DbContext

public class DbContext : IDisposable, IObjectContextAdapter
{
    public DbContext(string nameOrConnectionString);
}

Web.Config

 <add name="GEContext" connectionString="server=localhost;port=4040;uid=root;pwd=xxx;database=ge" providerName="MySql.Data.MySqlClient" />

现在我想将web.config中存在的"database = ge"替换为database = ge_ [schoolCode].在运行时如何解决?

now i want to replace "database=ge" present in web.config with database=ge_[schoolCode]. at runtime How can i go about it?

更新 我的解决方案不起作用.所以我再次说明问题.

UPDATE My solution did not work. so i am stating the problem once again.

Web.Config

我已将我的配置文件更改为以下文件(以前GEContext是唯一的连接字符串)

I have changed My config file to the following (previously GEContext was the only connection string)

<connectionStrings>
<add name="GEContext_sc001" connectionString="server=localhost;port=4040;uid=root;pwd=blabla;database=db_sc001" providerName="MySql.Data.MySqlClient" />
<add name="GEContext_sc002" connectionString="server=localhost;port=4040;uid=root;pwd=blabla;database=db" providerName="MySql.Data.MySqlClient" />

<appSettings>
     <add key="SchoolCodes" value="sc001,sc002"/>

这些是允许的学校代码

现在,当用户在登录屏幕上输入学校代码时,将根据SchoolCodes密钥中显示的代码进行验证.如果是,则应尝试连接到该特定连接的connectionString.现在,当我的代码进入

Now when the user enters schoolcode at login screen, it is validated against the codes present in SchoolCodes key. and if yes, then it should try to connect to the connectionString for that particular connection. Now when my code comes to

UserManager.FindAsync

在AccountController的登录功能中,尝试查找GEContext时会崩溃.那是在哪儿?以及我该如何更改?

in Login function of AccountController, it crashes trying to find GEContext. Where is that set? and how can i change it?

我已如下更改控制器中调用的存储库

I have changed the repository calling in controller as follows

private static string schoolCode = (string)System.Web.HttpContext.Current.Session["SchoolCode"];

    private AssessmentRepository repAssessments = new AssessmentRepository("name=GEContext_" + schoolCode);

UPDATE-2 ge.Web

IdentityConfig.cs

  public class ApplicationUserManager : UserManager<ApplicationUser, int>
{
    public ApplicationUserManager(IUserStore<ApplicationUser, int> store)
        : base(store)
    {
    }

     public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    {
        var manager = new ApplicationUserManager(new UserStore<ApplicationUser, Role, int, UserLogin, UserRole, UserClaim>(context.Get<ApplicationDbContext>()));
  ...........
 }

ge.Core中存在以下内容

The following is present in ge.Core

ApplicationDbContext

 public class ApplicationDbContext : IdentityDbContext<ApplicationUser, Role, int, UserLogin, UserRole, UserClaim>
{

     public ApplicationDbContext(string connString)
        : base(connString)
    {
        Database.SetInitializer(new MySqlInitializer());
    }

    public static ApplicationDbContext Create()
    {

        return new ApplicationDbContext("name=GEContext_");
    }
}

我如何将schoolCode从ge.web传递到ge.Core(答案应该很简单,但目前我无法解决)

How can i pass schoolCode from ge.web to ge.Core (answer should be straight forward but currently i cant get my head around it)

UPDATE-3

正如itikhomi所言,并从这篇文章中寻求帮助,我已经更改了我的代码如下

As told by itikhomi and taking help from this post I have changed my code as follows

  1. 在ApplicationDbContext类中添加了以下内容

  1. in ApplicationDbContext class added the following

公共静态ApplicationDbContext创建(字符串scCode){ 返回新的ApplicationDbContext("name = GEContext_" + scCode); }

public static ApplicationDbContext Create(string scCode){ return new ApplicationDbContext("name=GEContext_" + scCode); }

在AccountController登录中

in AccountController Login

var appDbContext = ApplicationDbContext.Create(model.SchoolCode);

var appDbContext = ApplicationDbContext.Create(model.SchoolCode);

            Request.GetOwinContext().Set<ApplicationDbContext>(appDbContext);

它仍然没有命中正确的数据库

it still does not hit the correct database

推荐答案

您有两种方法

1)

    using System.Data.SqlClient;

         public class Repository<TEntity> : IRepository<TEntity> where TEntity:class
        {
            protected readonly GEContext context;


            public Repository(string connString, string schoolCode) {
                context = new GEContext(connString);
                var connection = new SqlConnectionStringBuilder(context.Database.Connection.ConnectionString);
                connection.InitialCatalog = "YOUR_PREFIX_FROMSOMEWHERE"+schoolCode;
                context.Database.Connection.ConnectionString = connection.ConnectionString;
            }
         }

2)如果要在使用前打开连接时切换连接

2) if you wants to switch connection when it opened before use ChangeDatabase:

//open connection if it close
    context.Database.Connection.ChangeDatabase("DATABASE-NAME");

注意:如果使用ChangeDatabase连接,应该已经打开

NOTE: if use ChangeDatabase connection should be already opened

对于UPDATE3:

您需要这样做:

 public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()
            : base("DefaultConnection", throwIfV1Schema: false)
        {

        }

        public ApplicationDbContext(string schoolCode)
            : base(schoolCode)
        {
            var connection = new SqlConnectionStringBuilder(this.Database.Connection.ConnectionString);
            connection.InitialCatalog = "YOUR_PREFIX_FROMSOMEWHERE" + schoolCode;
            this.Database.Connection.ConnectionString = connection.ConnectionString;
        }

        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }
    }

在帐户控制器中:

public ApplicationSignInManager SignInManager
        {
            get
            {

                if (_signInManager == null)
                {
                    var code = HttpContext.Request.Form.Get("SchoolCode");//Get from FORM\QueryString\Session whatever you wants
                    if (code != null)
                    {
                        HttpContext.GetOwinContext().Set<ApplicationSignInManager>(new ApplicationSignInManager(_userManager, HttpContext.GetOwinContext().Authentication));
                    }
                    _signInManager = HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
                }

                return _signInManager;
            }
            private set
            {
                _signInManager = value;
            }
        }

 public ApplicationUserManager UserManager
        {
            get
            {
                if (_userManager == null)
                {
                    var code = HttpContext.Request.Form.Get("SchoolCode");//Get from FORM\QueryString\Session whatever you wants
                    if (code != null)
                    {
                        var appDbContext = new ApplicationDbContext(code);

                        HttpContext.GetOwinContext().Set<ApplicationDbContext>(appDbContext);
                        HttpContext.GetOwinContext().Set<ApplicationUserManager>(new ApplicationUserManager(new UserStore<ApplicationUser>(appDbContext))); //OR USE your specified create Method
                    }
                    _userManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
                }
                return _userManager;
            }
            private set
            {
                _userManager = value;
            }
        }

您的问题是在更改OWIN上下文之前创建了UserManager的存储区,在这种情况下,最好使用像

Your problem is in Store of UserManager is created before you change your OWIN context, in this case better to use DI like here

这篇关于如何在运行时更改dbcontext连接字符串中的数据库名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆