2

我努力使我的代码能够使用不同的连接字符串运行代码优先 EF 迁移,并最终让它工作。

我对这个问题的回答中概述了我使用的方法

困扰我的是,为了能够使用不同的连接字符串运行相同的代码,我必须

1)诉诸全局设置来存储连接字符串

2) 引入一个类,其存在导致代码行为不同。

这与我习惯的工作方式截然不同。这里使用的技术是否违反了坚实的原则?有没有其他不违反原则的做法?

更新:这里概述了一种不同的方法-可能更明智

4

1 回答 1

3

(所有这些都与这里的内容有关 Database.SetInitializer 的实际工作原理是什么?(EF 代码首先创建数据库并使用多个连接字符串应用迁移) - 但正在进入完全不同的方向 - 所以我认为这样做是有意义的分开。在此之前阅读那里)

更新:

这里变得越来越有趣了。我确实设法重现了您实际面临的问题。以下是我认为正在发生的事情的简短细分:

首先,这很“愉快”:

Database.SetInitializer(new CreateAndMigrateDatabaseInitializer<MyContext, MyProject.Migrations.Configuration>());
for (var flip = false; true; flip = !flip)
{
    using (var db = new MyContext(flip ? "Name=MyContext" : "Name=OtherContext"))
    {
        // insert some records...
        db.SaveChanges();
    }
}

(我使用了另一篇文章中的自定义初始化程序,它一起控制迁移/创建过程)

在没有初始化程序的情况下工作得很好。一旦我打开它,我遇到了一些奇怪的问题。

我删除了 Db-s(每个连接两个)。我希望要么不工作,要么创建一个数据库,然后在下一次传递中创建另一个(就像它所做的那样,没有迁移,只是“创建”初始化程序)。

发生了什么事,令我惊讶的是 - 它实际上是在第一遍创建了两个数据库吗?

然后,作为一个好奇的人:),我在MyContextctor 上设置了断点,并通过迁移器/初始化器进行了调试。再次为空/无 db-s 等。

它在我的通话中创建了第一个实例flip。然后在第一次访问“模型”时,它调用了初始化程序。Migrator 接管(没有 db-s)。在此期间,migrator.Update();它实际上构造了MyContext(我猜测是通过配置中的通用参数) - 并调用“默认”空 ctor。默认情况下,它具有“其他连接/名称” - 并且也创建了其他 Db。

所以,我认为这解释了你正在经历的事情。以及为什么您必须创建“工厂”来支持上下文创建。这似乎是唯一的方法。并设置一些“AppDomain”范围的“连接字符串”(实际上您确实发现了它),它不会被空的 ctor 调用“覆盖”。

我看到的解决方案是——你只需要通过工厂运行所有东西——并在那里“翻转”连接(不需要静态连接,只要你的工厂是单例的。

对于官方初始化程序,这实际上根本不起作用(至少我的测试) MigrateDatabaseToLatestVersion- 以及我使用另一个初始化程序的原因。

于 2013-04-07T01:16:52.510 回答