我使用迁移(EF 5.0)和代码优先有一个有趣的效果:
我创建了一些带有 GUID 主键的模型。 (顺便说一句:对我来说重要的是,SQL Server 使用 NEWSEQUENTIALID()
,这似乎是当前版本中的默认值)
在某些时候,我激活了迁移。我在初始迁移中添加了一些代码,这主要是 .Index()
根据需要。
当我删除数据库并调用 update-database 时,出现以下错误:
无法更新数据库以匹配当前模型,因为存在待处理的更改并且自动迁移已禁用。将挂起的模型更改写入基于代码的迁移或启用自动迁移。将 DbMigrationsConfiguration.AutomaticMigrationsEnabled 设置为 true 以启用自动迁移。您可以使用 Add-Migration 命令将挂起的模型更改写入基于代码的迁移。
我尝试了 AutomaticMigrationsEnabled = true
,它无需更改或添加任何内容即可工作!
但由于我不想要 AutomaticMigrationsEnabled
,我也尝试再次删除数据库,调用 update-database
,然后调用 add-migration
。我最终得到了一个似乎没有改变任何东西的额外迁移(见下文)。我还尝试将这些行添加到初始迁移的底部 - 但这并没有改变任何东西。
模型之一:
[Table(Speaker.TABLENAME)]
public class Speaker : BaseModel
{
public const String TABLENAME = "Speaker";
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[Required]
[MaxLength(50, ErrorMessage = "Name must be 50 characters or less")]
public string Name { get; set; }
}
初始迁移代码:
public partial class InitialCreate : DbMigration
{
public override void Up()
{
// [...]
CreateTable(
"dbo.Speaker",
c => new
{
Id = c.Guid(nullable: false, identity: true),
Name = c.String(nullable: false, maxLength: 50),
})
.PrimaryKey(t => t.Id)
.Index(t => t.Name, true, false); // added manually: unique Name
// [...]
}
}
internal sealed class Configuration : DbMigrationsConfiguration<MyProject.Repositories.DBContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(MyProject.Repositories.DBContext context)
{
// ...
}
}
下面是 add-migration 创建的代码:它似乎没有做任何新的事情 - 也许我错过了什么?
public partial class UnneccessaryMigration : DbMigration
{
public override void Up()
{
// isn't this the exact same code from InitialMigrations?
AlterColumn("dbo.Speaker", "Id", c => c.Guid(nullable: false, identity: true));
// ...
}
public override void Down()
{
//...
AlterColumn("dbo.Speaker", "Id", c => c.Guid(nullable: false));
}
}
所以我很好奇:我做了什么让迁移迷失方向?我能做些什么来让它只使用一个初始迁移?
解决方案:以下解决方法为我做了:
我删除了数据库和所有迁移,如下所述:https://stackoverflow.com/a/11679386/3168401 已执行 Enable-Migrations + Add-Migration Initial 将我手工制作的 .Index() 更改合并到文件中。现在 Update-Database 再次工作 - 在删除数据库时也会重复。
我还尝试再次删除数据库,称为更新数据库,然后添加迁移。我最终得到了一个似乎没有改变任何东西的额外迁移(见下文)
基于以上细节,我认为你先做了最后一件事。如果您在 Add-migration
之前运行 Update database
,它不会使用您的迁移架构更新数据库。首先,您需要添加迁移,然后运行更新命令。
使用包管理器控制台按此顺序尝试它们。
PM> Enable-migrations //You don't need this as you have already done it
PM> Add-migration Give_it_a_name
PM> Update-database
实体框架确实存在一些关于身份字段的问题。
You can't add GUID identity on existing table
Migrations: does not detect changes to DatabaseGeneratedOption
这些都没有准确描述您的问题,并且额外迁移中的 Down() 方法很有趣,因为当您在初始迁移中的 CREATE TABLE 似乎设置它时,它似乎试图从列中删除 IDENTITY!
此外,如果您使用 Update-Database -Script
或 Update-Database -Verbose
查看从这些 AlterColumn
方法运行的 sql,您将看到 Up
和 Down
中的 sql 是相同的,实际上什么都不做。 IDENTITY 保持不变(对于当前版本 - EF 6.0.2 及更低版本) - 如我链接到的前 2 个问题中所述。
我认为您应该删除额外迁移中的冗余代码并暂时使用空迁移。您可以订阅/投票支持要解决的问题。
参考:
Change IDENTITY option does diddly squat
Switch Identity On/Off With A Custom Migration Operation
尝试这个:
PM> Enable-migrations -force
PM> Add-migration MigrationName
PM> Update-database -force
对我来说,我在 Visual Studio 2015 中解决了如下问题:从视图菜单中单击其他窗口,然后单击包管理器控制台,然后运行以下命令:
PM> enable-migrations
已在项目“mvcproject”中启用迁移。要覆盖现有的迁移配置,请使用 -Force 参数。
PM> enable-migrations -Force
检查上下文是否针对现有数据库...为项目 mvcproject 启用了代码优先迁移。
然后在迁移文件夹下添加迁移名称,它将通过运行以下命令在解决方案资源管理器中添加您需要的类
PM>Add-migration AddColumnUser
最后更新数据库
PM> update-database
使用 VS2019 时,MVC5 - 在 Migrations 文件夹下查找文件 Configuration.cs 编辑:AutomaticMigrationsEnabled = true
回答你的一般问题
所以我很好奇:我做了什么让迁移迷失方向?我能做些什么来让它只使用一个初始迁移?
在我合并了几个分支并且迁移对数据库的当前状态感到困惑之后,我刚刚收到了与您相同的错误消息。最糟糕的是,这只发生在客户端的服务器上,而不是我们的开发系统上。
在试图弄清楚那里发生了什么时,我遇到了这个极好的微软指南:
Microsoft's guide to Code First Migrations in Team Environments
虽然该指南是为解释团队中的迁移而编写的,但它也给出了我发现的关于迁移如何在内部工作的最佳解释,这很可能会导致对您所看到的行为的解释。对于使用 EF6 或更低版本的任何人来说,花一个小时阅读所有这些内容是非常值得的。
对于在合并迁移后通过该错误消息提出此问题的任何人,generating a blank migration with the current state of the database 的技巧为我解决了问题,但请务必阅读整个指南以了解该解决方案是否适合您的情况。
我遇到了这个问题,上面的建议没有帮助。我发现添加迁移读取当前状态并创建当前模型的签名。您必须在修改之前修改您的模型。所以顺序是。
修改模型运行添加迁移
我做了相反的事情并在修改我的模型(它是空的,所以我添加了新列)之前添加了迁移,然后运行了我的代码。
希望这可以帮助。
如果您首先基于现有数据库将上下文模型设置为代码,那么您必须进行设置迁移:
Add-Migration InitialCreate –IgnoreChanges
Update-database -force
然后更改您的上下文模型并设置:
Add-migration RemoveIspositive
Update-database -force
我知道这是一个非常古老的线程。但是,想分享我如何在我的场景中遇到该消息,以防它可能对其他人有所帮助
我在本地计算机上创建了一个 Add-Migration
我的解决方案是运行 update-database -Script -TargetMigration <migration_name_from_merge>
,然后运行我的 update-database -Script -TargetMigration <migration_name>
,它生成了 2 个脚本,我可以在本地数据库上手动运行这些脚本。
不用说上面的经验是在我的本地机器上。
add-migration
并运行update database
以添加这些更改。