同时,我至少找到了问题的原因。如果您不想阅读我完成的所有步骤,只需向下滚动到本文末尾的 Edit1。
我目前面临 EF 6 的问题,我不知道这是设计上的错误还是我对 EF 的了解不够:(
我在一个解决方案中有3 个项目:一个服务器项目、一个客户端项目和一个模型项目。
该模型包含我的服务器和客户端的上下文类使用的实体,它们中的每一个都在我的服务器和客户端项目的命名空间中。
我的上下文类(都在模型命名空间内)包含2 个 DBSet对象:[Srv|Cli]Entity和CoreEntity。两者都是我的“真实”实体继承自的抽象类,因此我不必在上下文类中定义每个实体。
结果是为从这些基类中的每一个继承的每个实体创建了一个新表,并且为这些基类中的每一个本身创建了一个名为CoreEntityRegistry和[Srv|Cli]EntityRegistry的表。
我做的第一件事是启用迁移,添加初始迁移和更新数据库,没有任何问题。
比我在客户端代码和数据建模上工作,然后启用迁移并添加初始迁移。在这一点上,我不再记得是否进行了数据库更新,但我想是这样,因为如果没有,我会收到一些异常,试图访问在调试期间无法使用的数据库元素。
回到模型项目,我为服务器编辑了一些实体,我也为服务器和客户端(= Core)编辑了一些实体。
比我再次运行Add-Migration
服务器项目,但这次 EF 抱怨未决迁移。实际上这是不可能的,但我想我只是Update-Database
再次跑来确定。
该命令运行成功。
但是一旦我Add-Migration
再次尝试:来自 EF 的相同未决错误。
查看数据库表__MigrationHistory,我可以看到我的迁移,但ContextKey设置为LRCM.Client.Migrations.Configuration,而不是LRCM.Server.Migrations.Configuration,这很可能是我仍然处于幽灵挂起状态的原因。
这是我的第一个谜团:这怎么可能?启用迁移时,我为正确的ProjectName、ProjectStartUpName和ContextTypeName指定了参数。甚至尝试指定Configuration或ConfigurationTypeName参数而不进行任何更改。
长话短说,我真的尝试了我能想到的一切来解决这个问题:重命名配置类名称、更改命名空间(每个上下文一个)、将 MigrationNamespace 设置为迁移配置、手动将ContextKey设置为配置等。
最后我想(项目仍处于初始状态)我只是再次删除服务器和客户端的数据库,从服务器和项目中删除所有迁移文件和文件夹,将我的上下文类放入每个相应的项目(客户端,服务器)和现在只为我的服务器启用迁移,以确保在我也为客户端项目启用迁移之前,该服务器正在工作。
跑步Add-Migration
看起来很有希望,但跑步Update-Database
教会了我其他东西。
现在我收到(我在上面简要介绍的测试期间也收到了)一个关于已经存在的表的错误。相关表是我的 CoreEntities 表(也由客户端上下文使用),但我的迁移文件不包含两次这样的CREATE语句。我想以某种方式迁移试图合并我的客户端和我的服务器上下文 -但为什么呢?
它们之间没有联系,只是它们共享一些实体。
再次查看数据库站点,我可以看到我创建的所有表以及在 __MigrationHistory 表中 - 惊喜:仍然是相同的 ContextKey值。
这是我的第二个谜: 为什么 ContextKey 仍然是解决方案中使用的第一个?它是否缓存在某个地方?为什么迁移尝试添加我的表两次,尽管迁移文件只有一个CREATE语句?
对于一些代码示例(此处的代码功能不适合长代码输入),请参阅我昨天打开的另一个线程,但怀疑我不会在那里收到任何答案:MSDN 论坛
我真的很感激能得到任何帮助来解决这个问题。
问候,
汤姆
编辑1:
与此同时,我至少收效甚微。
我从服务器和客户端项目中删除了与迁移相关的所有内容。
在我的服务器上下文中为 CoreEntity 评论了我的 DBSet。
为服务器项目启用迁移。
成功添加了迁移文件。
成功更新数据库。
重置所有迁移内容,这次使用 CoreEntity 的上下文。
添加迁移和更新数据库再次成功。
为客户项目启用迁移。
成功添加迁移和更新数据库。
在为客户端项目启用迁移之前,我在 DB 中再次查看,这次我在__MigrationHistory中看到了两个条目。一个是旧的(错误的)ContextKey,一个是正确的。
因此,我再次删除了所有数据库并执行了Update-Database
. 而这一次只有 1 个正确的条目。
但现在我又有了未决的问题。不管我多久跑一次Update-Database
。
这使我得出了一些我必须检查的其他结论:
如果我从项目文件夹中删除数据库文件,迁移会警告缺少数据库。但是,如果我再次将此文件添加为新数据库,它将起作用。
我看到的问题(我想我知道)是迁移更新了我的构建的AppData文件夹下的数据库,它在调试期间使用它,但检查(无论出于何种原因)在我的项目的AppData文件夹中只有一个数据库文件的数据库没有任何桌子。
我是对的,至少找到了原因:
当我执行 Update-Database 时,它连接到构建文件夹结构中的数据库,而不是项目文件夹结构中的数据库。
所以我的最后一个问题(我也将更改标题)是: 为什么基于 EF 代码的迁移检查项目 DB 文件中的迁移,但只写入构建的 DB 文件中的 DB 文件?看起来几乎像一个错误?!