我正在尝试将迁移应用到我的数据库。
最初,数据库经过逆向工程,首先使用EF电动工具进行编码。在我的数据库中,表名都以tbl_ [NAME]开头,因此在完成逆向工程后,我所有的模型都有相同的约定。由于模型名称在modelMAP中映射到每个模型的表名,我决定重命名所有生成的模型以在创建迁移时删除“tbl_”并查看“UP”方法,我可以看到EF希望DropForeignKey在所有受影响的表,所有表,然后删除表!什么呢?
由于我的数据库很大,我将在迁移UP方法中只显示几行代码。
DropForeignKey("dbo.tbl_AssetFileLocations", "AssetFileID", "dbo.tbl_AssetFiles");
DropForeignKey("dbo.tbl_AssetFileLocations", "StorageLocationID", "dbo.tbl_StorageLocations");
...
DROP ALL FOREIGN KEYS ON ALL TABLES
...
DropIndex("dbo.tbl_AssetFileLocations", new[] { "AssetFileID" });
DropIndex("dbo.tbl_AssetFileLocations", new[] { "StorageLocationID" });
...
DROP ALL INDEXES
...
CreateTable(
"dbo.tbl_AssetFileLocations",
c => new
{
AssetLocationID = c.Guid(nullable: false),
AssetFileID = c.Guid(nullable: false),
StorageLocationID = c.Guid(nullable: false),
DateCreatedonStorage = c.DateTime(nullable: false),
})
.PrimaryKey(t => t.AssetLocationID)
.ForeignKey("dbo.tbl_AssetFiles", t => t.AssetFileID, cascadeDelete: true)
.ForeignKey("dbo.tbl_StorageLocations", t => t.StorageLocationID, cascadeDelete: true)
.Index(t => t.AssetFileID)
.Index(t => t.StorageLocationID);
...
CREATE ALL OTHER TABLES
...
DropTable("dbo.tbl_AssetFileLocations");
...
DROP ALL TABLES
...
我在数据库中没有数据,所以虽然我不确定为什么EF决定放弃所有表并重新创建它,但这在我的实验中并不是问题。但是,我想了解为什么更改模型名称会导致完整的数据库重建(新名称映射到与DB进行逆向工程时相同的表名!)
我的主要问题
尝试应用迁移时,我最终陷入了一个循环错误风暴。
第一次尝试会出错: FK_dbo.tbl_AssetFileLocations_dbo.tbl_AssetFiles_AssetFileID'不是约束。 无法删除约束。查看以前的错误。
所以我想好的,我会评论DropForeignKey //DropForeignKey("dbo.tbl_AssetFileLocations“,”AssetFileID“,”dbo.tbl_AssetFiles“);
然后它在下一个具有相同(上下文)错误的dropForeignKey上出错。因此,作为实验,我会注释掉所有DropForeignKey语句。
重新运行update-database命令,然后会出现错误消息:
无法删除索引'dbo.tbl_AssetFileLocations.IX_AssetFileID',因为它不存在或您没有权限。
并且一个接一个地抱怨所有DropIndex语句。所以作为一个实验,我会注释掉所有并尝试更新数据库
因为我们可以看到UP方法尝试做的下一件事是添加所有表!我当然得到错误: 数据库中已经有一个名为“tbl_AssetFileLocations”的对象。
所以我觉得EF在这里有点沉闷,你在创建它们之后试图放弃它们!所以我改变Drop表命令的顺序,以便它们出现在Create Table命令之前,因为这更有意义。
由于这只是EF代码的首次实验和迁移,所以很酷。我很高兴EF能够删除整个数据库模式并重建它。
因此,现在Drop Table命令位于正确的位置,我重新运行Update-Database以获得最终的循环错误:
无法删除对象'dbo.tbl_Assets',因为它是由FOREIGN KEY约束引用的。
对我自己而言,我认为“是的,这是外键的约束,你在本次练习开始时拒绝放弃。”
那么我从哪里开始呢。从这个实验看来,除了EF网站上给出的简单示例之外,Code-First迁移似乎并不适用于所有人!
是否有人对大型数据库进行了逆向工程并成功进行了代码更改并将其迁移到数据库?
我是否应该先忘记代码并首先返回数据库(我宁愿不 - 我首先喜欢代码的想法)?
请帮助EF人。
答案 0 :(得分:0)
您是否打算重命名您的上下文类而不是数据库中的表?
从头开始再次生成上下文,然后在重构/重命名代码之前添加[TableName(“tbl_ContextClassName”)]属性。
我的猜测是,如果数据库不是您的更改,您可能只有在所有类名和属性名都使用属性设置其数据库名后才重构 - 这是为了避免重命名'约定优于配置'重命名类时的表,如果重命名属性,则重命名列。