【问题标题】:EF6 DBContext Dynamic Connection StringEF6 DBContext 动态连接字符串
【发布时间】:2014-02-05 13:42:44
【问题描述】:
public partial class ProcessContext : DbContext
{
    static ProcessContext()
    {
        Database.SetInitializer<ProcessContext>(null);
    }

    public ProcessContext()
        : base("Name=ProcessCS") //Comes from Config File
    {
    }

    --DBSets 
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
       --Code
    }
}

这是一个多租户数据库,我们有 3 个不同的数据库。集中式数据库位于公共位置,不会更改。这是存储其余数据库详细信息的地方。我需要创建连接字符串@runtime,详细信息将来自这个集中式数据库。有人可以告诉我怎么做吗?

我尝试使用以下代码,但它不起作用。这里会调用这个方法

public ProcessContext()
    : base(nameOrConnectionString: ConnectionString())
{
}

private static string ConnectionString()
{
    SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder();
    sqlBuilder.DataSource = "XXX";
    sqlBuilder.InitialCatalog = "YYY";
    sqlBuilder.PersistSecurityInfo = true;
    sqlBuilder.IntegratedSecurity = true;
    sqlBuilder.MultipleActiveResultSets = true;

    EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();
    entityBuilder.ProviderConnectionString = sqlBuilder.ToString();
    entityBuilder.Metadata = "res://*/";
    entityBuilder.Provider = "System.Data.SqlClient";

    return entityBuilder.ToString();
}

【问题讨论】:

  • “但它不起作用” - 什么不起作用?您收到错误消息吗?
  • 关于如何使用动态上下文的解决方案stackoverflow.com/a/16133150/1347784
  • @StevenV 当我尝试上面的代码时,我收到一条错误消息“登录失败。登录来自不受信任的域,不能用于 Windows 身份验证”。可能的解决方案是什么?
  • 非常感谢,它工作正常。我在我的代码中发现了一点错误。

标签: entity-framework asp.net-mvc-4 .net-4.5 dbcontext


【解决方案1】:

对于 SQL Server 连接,覆盖实体容器类:(适用于 EF6、SQL server 2012 express、VS2013)

public partial class PxxxxEntities
{
    private PxxxxEntities(string connectionString)
        : base(connectionString)
    {
    }

    public static PxxxxEntities ConnectToSqlServer(string host, string catalog, string user, string pass, bool winAuth)
    {
        SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder
        {
            DataSource = host,
            InitialCatalog = catalog,
            PersistSecurityInfo = true,
            IntegratedSecurity = winAuth,
            MultipleActiveResultSets = true,

            UserID = user,
            Password = pass,
        };

        // assumes a connectionString name in .config of MyDbEntities
        var entityConnectionStringBuilder = new EntityConnectionStringBuilder
        {
            Provider = "System.Data.SqlClient",
            ProviderConnectionString = sqlBuilder.ConnectionString,
            Metadata = "res://*/DbModel.csdl|res://*/DbModel.ssdl|res://*/DbModel.msl",
        };

        return new PxxxxEntities(entityConnectionStringBuilder.ConnectionString);
    }
}

【讨论】:

【解决方案2】:

您应该将普通连接字符串传递给DbContext 构造函数,而不是实体连接字符串。所以试着改变你的代码如下:

public ProcessContext()
    : base(ConnectionString())
{
}

private static string ConnectionString()
{
    SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder();
    sqlBuilder.DataSource = "XXX";
    sqlBuilder.InitialCatalog = "YYY";
    sqlBuilder.PersistSecurityInfo = true;
    sqlBuilder.IntegratedSecurity = true;
    sqlBuilder.MultipleActiveResultSets = true;

    return sqlBuilder.ToString();
}

【讨论】:

【解决方案3】:

你必须改变 Web.config

<connectionStrings>
<add name="DefaultConnection" connectionString="data source=mydb;initial catalog=mydatabase;persist security info=True;user id=sa;password=password;multipleactiveresultsets=True;application name=EntityFramework" providerName="System.Data.SqlClient" />
<add name="DataContext" connectionString="data source=mydb;initial catalog=mydatabase;persist security info=True;user id=sa;password=password;multipleactiveresultsets=True;application name=EntityFramework" providerName="System.Data.SqlClient" />
<!-- Here Add multiple database connection string  -->


在你必须修改 ProcessContext.cs 文件之后 一个创建默认连接的构造函数

public ProcessContext()
      :base("name=DefaultConnection"){
        //here code
       }

其他参数构造函数动态连接数据库

public ProcessContext(string DynamicConnectionString)
       :base(DynamicConnectionString){
// herer code }

这里的默认连接是“DefaultConnection”,但是你有给代码任何控制器的chnage连接字符串

ProcessContext db=new ProcessContext();//this is default connection

ProcessContext db=new ProcessContext("DataContext");//dynamic change connection string 

试试这个代码

【讨论】:

    【解决方案4】:

    这种方法对我很有效。我只是在我的 app.config 中添加了另一个命名连接字符串,然后将名称传递到下面的 GetDbContext() 静态方法中,如下所示。

    使用示例:

    var dbAlternate = PxxxxEntities.GetDbContext("PxxxxEntitiesAlternate")
    

    将以下内容添加到您的项目中:

    public partial class PxxxxEntities
    {
        private PxxxxEntities(string name)
            : base("name=" + name)
        {
        }
    
        public static PxxxxEntities GetDbContext(string name)
        {
            return new PxxxxEntities(name);
        }
    }
    

    【讨论】:

      【解决方案5】:

      尝试使用 app.config 文件。然后通过其名称调用所需的连接字符串:

      using System.Configuration;
      
      public ProcessContext()
          : base(ConnectionString("foo"))
      {
      }
      
      private static string ConnectionString(string connKey)
      {
          var conn = ConfigurationManager.ConnectionStrings[connKey].ConnectionString;
          return conn;
      }
      

      【讨论】:

        【解决方案6】:

        动态连接字符串 EF

        使用此代码:

            public Entities(): base(ConnectToSqlServer())
            {
            }
        
        
        
            public static string ConnectToSqlServer()
            {
                SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder
                {
                    DataSource = "ServerName",
                    InitialCatalog = "DatabaseName",
                    PersistSecurityInfo = true,
                    IntegratedSecurity = false,
                    MultipleActiveResultSets = true,
        
                    UserID = "Username",
                    Password = "Password",
                };
                var entityConnectionStringBuilder = new EntityConnectionStringBuilder
                {
                    Provider = "System.Data.SqlClient",
                    ProviderConnectionString = sqlBuilder.ConnectionString,
                    Metadata = "res://*/Data.Database.csdl|res://*/Data.Database.ssdl|res://*/Data.Database.msl",
                };
        
                return entityConnectionStringBuilder.ConnectionString;
            }
        

        【讨论】:

        • 虽然此代码可能会为 OP 的问题提供解决方案,但强烈建议您提供有关此代码为何和/或如何回答问题的额外上下文。从长远来看,只有代码的答案通常会变得毫无用处,因为未来遇到类似问题的观众无法理解解决方案背后的原因。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-02
        • 1970-01-01
        • 2018-05-20
        • 2023-03-25
        相关资源
        最近更新 更多