我正在使用 EF 5,我需要以某种方式入侵连接创建管道。这是我的情况。在生产中,我们有 2 个 SQL 服务器(我对此没有任何控制),我在我的 web.config 中指定了它们。如果一个连接失败,我需要尝试另一个。再一次,我知道 SQL 故障转移集群,但正如我所说,我无法控制它。
我尝试使用采用 DbConnection
的 DbContext
重载。然后我尝试自己打开连接,看是否成功,再传给EF。那里的问题是 EF 只想要一个关闭的连接。打开一个连接,然后关闭它,只是为了让 EF 再次打开它,这似乎真的很糟糕!
有没有更好的办法??
最佳答案
如果两个连接都在 Web.config 文件中指定,那么您应该使用 this overload DbContext 类。您需要做的就是传入在 <connectionStrings>
中找到的名称记录您尝试连接的内容,它将进入 Web.config 文件,获取该连接字符串,然后打开连接。
一个示例(将普通本地主机与 SQLEXPRESS 一起使用——很容易转换为您的过程)
<connectionStrings>
<add name="Connection1" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog = FirstDB;Integrated Security=True" providerName="System.Data.SqlClient;MultipleActiveResultSets=true;" />
<add name="Connection2" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog = SecondDB;Integrated Security=True" providerName="System.Data.SqlClient;MultipleActiveResultSets=true;" />
</connectionStrings>
然后在您的 DbContext 类中存在以下构造函数:
public MyDbContext(string connectionString) : base(connectionString)
{
}
在哪里connectionString
将是“Connection1”或“Connection2”。
编辑:根据评论,我认为您需要在 DbContext 上创建一个层,它只会为您进行切换。您可能需要考虑执行以下步骤:
1) 创建一个包含 DbContext 对象的类(我们称它为 ContextLayer)。这个类是否是静态的取决于你。您可能还想让它实现 IDisposable。
2) 在该项目的 Web.Config 文件中,确保有一个连接字符串条目用于您可能连接到的所有数据库。
3) 使用配置文件中找到的第一个连接字符串,在图层类上有一个方法可以为您提供 DbContext 对象。作为替代方案,您还可以将层本身变成一个存储库,它将 DbContext 对象作为私有(private)字段,并且只公开用于获取特定信息的存储库方法。
4) 在这个图层类中,有一个返回 int 的 SaveChanges() 方法,就像 DbContext.SaveChanges() 一样。在 SaveChanges() 内部检查连接是否良好。否则,检查 Web.Config 文件中的每个其他连接字符串条目并使用 DbContext 类的新实例(与当前类中的对象不同的对象)测试它们。如果其中一个有效,则执行将更改放在另一个 DbContext 类上的所有逻辑。如果您决定将其设为静态类,则可能需要根据您的需要将类上的 DbContext 对象设置为此上下文。
5) 如果所有上下文都不起作用,可能让方法返回 -1,并在屏幕上弹出无法保存的消息,因为找不到要保存到的数据库。
通过执行此编码一次,您将保证每次尝试保存到数据库时,只需对图层类进行 1 次非常简单的调用即可,即使它不起作用,您以一种简洁明了的方式向客户端显示它无法连接。
关于c# - 覆盖 Entity Framework 连接逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14203578/