如何在运行时更改dbcontext连接字符串中的数据库名称

时间:2017-07-26 01:09:33

标签: asp.net-mvc entity-framework

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

  • ge.Web
  • ge.BLL
  • ge.Core
  • ge.Entities
ge.Web中的

控制器初始化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" />

现在我想用database = ge_ [schoolCode]替换web.config中的“database = ge”。在运行时如何解决它?

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

的Web.Config

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

<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

现在,当用户在登录屏幕上输入学校代码时,将根据SchoolCodes键中的代码对其进行验证。如果是,那么它应该尝试连接到该特定连接的connectionString。现在我的代码来了

UserManager.FindAsync

在AccountController的登录功能中,它崩溃试图找到GEContext。那套在哪里?我怎么能改变它?

我更改了控制器中的存储库调用,如下所示

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

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(答案应该是直截了当但目前我无法理解它)

UPDATE-3

正如itikhomi所说并从this post那里获得帮助我改变了我的代码如下

    ApplicationLbContext类中的
  1. 添加了以下内容

    public static ApplicationDbContext Create(string scCode){         返回new ApplicationDbContext(“name = GEContext_”+ scCode);     }

  2. 在AccountController登录
  3. var appDbContext = ApplicationDbContext.Create(model.SchoolCode);

                Request.GetOwinContext().Set<ApplicationDbContext>(appDbContext);
    
  4. 它仍未找到正确的数据库

3 个答案:

答案 0 :(得分:1)

你有两种方式

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)如果要在使用ChangeDatabase之前打开连接时切换连接:

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

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

FOR 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存储,在这种情况下更好地使用DI here

答案 1 :(得分:1)

您可以将数据库更改为开放连接

context.Database.GetDbConnection().ChangeDatabase("");

答案 2 :(得分:0)

我在itikhomi的帮助下解决了它。发布最终代码..

<强> ApplicationDbContext

public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext("name=GEContext");
    }

<强>的AccountController

 public ApplicationUserManager UserManager {
        get
        {
            if (System.Web.HttpContext.Current.Session["SchoolCode"] == null)
                return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
            else
            {
                var appDbContext = ApplicationDbContext.Create(System.Web.HttpContext.Current.Session["SchoolCode"].ToString());//new ApplicationDbContext("name=GEContext", System.Web.HttpContext.Current.Session["SchoolCode"].ToString());

                HttpContext.GetOwinContext().Set<ApplicationDbContext>(appDbContext);
                HttpContext.GetOwinContext().Set<ApplicationUserManager>(new ApplicationUserManager(new UserStore<ApplicationUser, Role, int, UserLogin, UserRole, UserClaim>(appDbContext)));

                return HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
            }
        }
        private set
        {
            _userManager = value;
        }
    }