如何使用C#在运行时覆盖Web.config文件中设置的数据库?

时间:2016-02-03 15:40:54

标签: c# asp.net asp.net-mvc-4 asp.net-mvc-5 connection-string

我有一个Context类,它将接受构造函数中的连接名称。然后它允许我连接到特定的服务器。

我想知道如何在运行时更改该连接的默认数据库。

这就是我所做的

在Web.config文件中,我添加了以下连接字符串

  <connectionStrings>
    <add name="BaseConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=ScripterDynamo;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\ScripterDynamo.mdf" providerName="System.Data.SqlClient" />
    <add name="conn1" connectionString="Server=Serv1;Database=db1;UserId=myUser; Password=myPassword;" providerName="System.Data.SqlClient" />
    <add name="conn2" connectionString="Server=Serv2;Database=db2;UserId=myUser; Password=myPassword;" providerName="System.Data.SqlClient" />
    <add name="conn3" connectionString="Server=Serv3;Database=db3;UserId=myUser; Password=myPassword;" providerName="System.Data.SqlClient" />
    <add name="conn4" connectionString="Server=Serv4;Database=db4;UserId=myUser; Password=myPassword;" providerName="System.Data.SqlClient" />
  </connectionStrings>

然后我创建一个简单的上下文类,如此

using ScripterEngine.Models;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Core.EntityClient;
using System.Data.SqlClient;
using System.Linq;
using System.Web;

namespace ScripterEngine.DataAccessLayer
{
    public class BaseContext : DbContext
    {
        public DbSet<Campaign> Campaign { get; set; }
        public DbSet<TableMeta> Campaign { get; set; }

        public BaseContext(string connectionName = "BaseConnection")
            : base(connectionName)
        {

        }
    }
}

使用此上下文类,我可以像这样连接到conn4

BaseConnection conn4 = BaseConnection("conn4");

这里唯一的问题是连接&#34; conn4&#34;将连接到名为db4的数据库,该数据库默认设置在连接字符串中。在大多数情况下,这是期望和好的。但就我而言,我希望能够在运行时更改要连接的数据库。

我的问题是,如何动态更改数据库?有没有办法在上下文类中添加一个只覆盖默认数据库的方法?

已更新

以下是我更改了我的上下文类,希望setDatabase方法允许我在运行时更改数据库

using ScripterEngine.Models;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Core.EntityClient;
using System.Data.SqlClient;
using System.Linq;
using System.Web;

namespace ScripterEngine.DataAccessLayer
{
    public class BaseContext : DbContext
    {
        protected string connectionName;
        public DbSet<Campaign> Campaign { get; set; }
        public DbSet<TableMeta> TableMeta { get; set; }

        public BaseContext(string connName = "BaseConnection")
            : base(connName)
        {
            connectionName = connName;
        }

        public BaseContext setDatabase(string databaseName)
        {
            var connection = System.Configuration.ConfigurationManager.ConnectionStrings[connectionName].ConnectionString;

            //change the database before creating the new connection
            return new BaseContext(connection);
        }


    }
}

我会像这样使用它

        BaseContext db1 = new BaseContext("conn4";
        var connToNewDB = db1.setDatabase("SomeNewDatabase");

3 个答案:

答案 0 :(得分:0)

你可以做这样的事情,这个ExampleData只是一个理解的例子,你可以在这里讨论你需要的值,连接字符串保持这样:

<connectionStrings>
        <add name="ConnectionString.Properties.Settings.CustomConnectionString"
            connectionString="Persist Security Info=True" providerName="System.Data.SqlClient" />
    </connectionStrings>

这只是初始化数据的示例     使用System;

namespace ConnectionStringCustom
{
    public static class ExampleData
    {
        public static String connUserName = "user";
        public static String connPassword = "pass";
        public static String connServerName = "servername";
        public static String connDatabaseName = "databasename";
    }
}



namespace ConnectionStringCustom.Properties
   {

   internal sealed partial class Settings
      {


      void Settings_SettingsLoaded( object sender, System.Configuration.SettingsLoadedEventArgs e )
         {
             this["CustomConnectionString"] = "Data Source=" + ExampleData.connServerName + ";"
                                          + "Initial Catalog=" + ExampleData.connDatabaseName + ";"
                                          + "Persist Security Info=false;"
                                          + "User ID=" + ExampleData.strConnUserName + ";"
                                          + "Password=" + ExampleData.connPassword + ";";
         }

      }

   }

有了这个,你可以改变所有的礼仪。

编辑: 看看你的改变我想你可能需要像

这样的东西

https://stackoverflow.com/a/7692708/5842138

但我认为这不是一个好习惯,为什么你不简单地创建许多ConnectionStrings?

希望这个帮助

答案 1 :(得分:0)

尝试设置DbConnection.ConnectionString属性。

dataContextInstance.Database.Connection.ConnectionString = "new connection string";

但我不确定您是否需要在更改连接字符串后重新初始化某些属性/代码。

答案 2 :(得分:0)

我创建了2个上下文。

  1. BaseContext:此上下文不会更改,我使用它来使用Code first方法设计我的应用程序。

  2. DynamicContext:此上下文将在运行时更改。

  3. 为了让DynamicContext起作用,我在连接文件中创建了一个动态连接。

    我基本上将这个添加到我的块

    namespace MyApp.DataAccessLayer
    {
        public class DynamicContext : DbContext
        {
            protected string connectionName = "DynamicConnection";
    
            protected string myServerName;
    
            protected string myUserId;
    
            protected string myPassword;
    
            /**
             * Created the connection to the server using the giving connection string name.
             * This constructor will allow you to connect to any connection string found in the Web.config file
             * 
             * @param connName
             */
            public DynamicContext(string serverName = null, string userID = null, string password = null)
                : base("DynamicConnection")
            {
                myServerName = serverName;
    
                myUserId = userID;
    
                myPassword = password;
            }
    
            /**
             * This constructor will allow you to construct a context by giving a string and it can only be call from the class itself
             * 
             */
            private DynamicContext(string connectionString)
                : base(connectionString)
            {
            } 
    
    
            /**
             * Changes the default database
             * 
             * @param databaseName
             */
            public DynamicContext setDatabase(string databaseName)
            {
                //Get the existing string for dynamic connection
                var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings[connectionName].ConnectionString;
    
                //convert the existsing string into an object
                SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectionString);
    
                //change the database before creating the new connection
                builder.InitialCatalog = databaseName;
    
                if (myServerName != null){
                    builder.DataSource = myServerName;
                }
    
                if (myUserId != null){
                    builder.UserID = myUserId;
                }
    
                if (myPassword != null){
                    builder.Password = myPassword;
                }
    
                return new DynamicContext(builder.ConnectionString);
            }
    
        }
    }
    

    然后我创建了一个像这样的新上下文类

    使用System; 使用System.Collections.Generic; 使用System.Data.Common; 使用System.Data.Entity; 使用System.Data.Entity.Core.EntityClient; 使用System.Data.SqlClient; 使用System.Linq; 使用System.Web;

    //Create a dynamic context, note that you can also change the username and the password of the default user by using the second and third parameters.
    var dbDynamic = new DynamicContext(serverName);
    
    //Finally, you can set the correct table
    var conn1 = dbDynamic.setDatabase('table1');
    
    //If you want to connect to a different table
    var conn2 = dbDynamic.setDatabase('table2');
    

    然后我就这样使用

    AttributeError: 'NotImplementedType' object has no attribute 'flat'