EF6 DBContext 动态连接字符串

22
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个不同的数据库。集中式数据库位于公共位置,并且不会更改。这是存储其余数据库详细信息的地方。我需要在运行时创建连接字符串,其中详细信息将来自此集中式数据库。请问有人知道如何操作吗?

我尝试了以下代码,但它没有起作用。该方法将在此处调用

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();
}

1
“但它没有起作用” - 它的哪个部分出了问题?你收到了错误信息吗? - Steven V
如何使用动态上下文的解决方案 https://dev59.com/9mUp5IYBdhLWcg3wHUvi#16133150 - phil soady
@StevenV 当我尝试运行上述代码时,我遇到了一个错误,提示“登录失败。登录来自不受信任的域,无法与 Windows 认证一起使用”。这可能有什么解决方法? - Sarthak Shah
非常感谢,代码运行良好。我在我的代码中发现了一个小错误。 - Sarthak Shah
6个回答

24

对于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);
    }
}

1
以上方法对我确实有效,让我省去了很多麻烦。 - Tim Butterfield
这是一个不错的解决方案。不过,我想问一下,"MultipleActiveResultSets=true" 这部分在EF6中是否建议使用?https://msdn.microsoft.com/en-us/library/h32h3abf(v=vs.110).aspx - Harvey Darvey

15

你应该向 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();
}

@luskan,你能帮我解决这个问题吗?http://stackoverflow.com/questions/21181253/repository-pattern-with-entity-framework-and-mvc4-building-dynamic-connection-st - Gautham Nayak

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",但如果你在任意控制器中更改了连接字符串给定代码,则需要进行更改。

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

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

试试这段代码


0

这种方法对我很有效。我只需在我的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);
    }
}

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

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

private static string ConnectionString(string connKey)
{
    var conn = ConfigurationManager.ConnectionStrings[connKey].ConnectionString;
    return conn;
}

0

动态连接字符串 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;
    }

1
虽然这段代码可能解决了 OP 的问题,但强烈建议您提供有关为什么和/或如何回答问题的其他上下文。仅提供代码答案通常在长期内变得无用,因为未来遇到类似问题的观众无法理解解决方案背后的推理。 - E. Zeytinci

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接