在 EF 6 中的运行时更改连接字符串

Change Connection String at Runtime in EF 6

我主要通过 using 语句使用我的 dbcontext:

using (var context = new MyContext())
{
}

但是我后来不得不添加一个带有更改数据库功能的项目。我发现我可以将我的 dbcontext 构造函数更改为:

public MyContext(string connectionstring)
        : base(connectionstring)
{
}

我为连接字符串创建了一个 class 和一个 属性:

public static class DbAccessor
{
    public static string ConnectionStringForContext { get; set; }
}

我在开始时设置了这个 属性,我的使用语句如下所示:

using (var context = new MyContext(DbAccessor.ConnectionStringForContext) 
{}

它有效,但我的连接字符串现在无处不在,我觉得我不应该用连接字符串那样做。有更好的方法吗?如果我想更改它们,处理连接字符串的最佳方法是什么?我应该停止使用这些 using 语句吗?

我看过这个问题:Entity Framework change connection at runtime

但不同之处在于,我有一个有效的解决方案,但我不想让我的连接字符串无处不在。如果我在每个 using 语句中使用该扩展方法。这几乎就像我的解决方案一样,在每个 using 语句中只增加一行...

连接字符串只有一处,没关系。 如果您想要更改连接字符串,您只需更改 DbAccessor.ConnectionStringForContext,这很好。 或者,如果您不想在构造函数中使用参数,您可以尝试使用此 question.

的解决方案

您可以在使用连接字符串的上下文中尝试静态工厂方法(或工厂 class,无论您喜欢哪个),如下所示:

public class MyContext : ...
{
    public MyContext(string connectionstring)
        : base(connectionstring)
    {
    }

    public static MyContext Create()
    {
        return new MyContext(DbAccessor.ConnectionStringForContext);
    }
}

然后您可以像这样创建上下文:

using (var context = MyContext.Create())
{
}

如果我对您的理解正确,您需要能够支持您的应用程序连接到多个数据库。你几乎可以像现在这样做,但是在你的 DBAccessor class 上说了两个属性,删除设置并从你的配置中获取相关连接,这样你的配置总是在应用程序配置中维护.

public static class DbAccessor
{
    public static string ConnectionStringForDBOne { get { return ConfigurationManager.ConnectionStrings["DBOne"].ConnectionString} }
    public static string ConnectionStringForDBTwo { get { return ConfigurationManager.ConnectionStrings["DBTwo"].ConnectionString} }
}

然后添加一些静态创建器以使生活更轻松:

public MyContext(string connectionstring)
        : base(connectionstring)
{
    public static MyContext CreateContextDBOne()
    {
        return new MyContext(DbAccessor.ConnectionStringForDBOne);
    }

    public static MyContext CreateContextDBTwo()
    {
        return new MyContext(DbAccessor.ConnectionStringForDBTwo);
    }
}

然后在代码中使用它们:

using (var context = MyContext.CreateContextDBOne())
{
}

using (var context = MyContext.CreateContextDBTwo())
{
}