我使用迁移(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{ 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
执行启用 - 迁移+添加迁移初始
合并我的手工.Index()更改到文件中.现在,Update-Database再次运行 - 在删除数据库时也会重复运行.
Kaf.. 102
我还尝试再次删除数据库,称为update-database,然后添加迁移.我最终得到了一个似乎没有改变任何东西的额外迁移(见下文)
基于以上细节,我认为你先做了最后一件事.如果Update database
之前运行Add-migration
,则不会使用迁移模式更新数据库.首先,您需要添加迁移,然后运行update命令.
使用包管理器控制台按此顺序尝试它们.
PM> Enable-migrations //You don't need this as you have already done it PM> Add-migration Give_it_a_name PM> Update-database
也许我在这一点上错了,但我希望能够在需要时重新创建数据库.初始迁移不是那样做的吗?在我偶然发现上面描述的效果之前,使用update-database创建数据库工作正常.一旦我添加了"空白的孩子"迁移步骤,它也会起作用. (2认同)
Colin.. 9
实体框架确实在身份字段方面存在一些问题.
您无法在现有表上添加GUID标识
迁移:不检测DatabaseGeneratedOption的更改
逆向工程不会将具有默认NEWSEQUENTIALID()的GUID键标记为存储生成的标识
这些都没有完全描述您的问题,并且额外迁移中的Down()方法很有趣,因为当初始迁移中的CREATE TABLE似乎设置它时,它似乎试图从列中删除IDENTITY!
此外,如果您使用Update-Database -Script
或Update-Database -Verbose
查看从这些AlterColumn
方法运行的sql,您将看到sql在Up
和中是相同的Down
,并且实际上什么都不做.IDENTITY保持不变(对于当前版本 - EF 6.0.2及更低版本) - 如我链接的前两个问题中所述.
我认为您应该删除额外迁移中的冗余代码,并暂时使用空迁移.您可以订阅/投票支持要解决的问题.
参考文献:
改变IDENTITY选项确实蹲下了
使用自定义迁移操作打开/关闭标识
实体框架确实在身份字段方面存在一些问题.
您无法在现有表上添加GUID标识
迁移:不检测DatabaseGeneratedOption的更改
逆向工程不会将具有默认NEWSEQUENTIALID()的GUID键标记为存储生成的标识
这些都没有完全描述您的问题,并且额外迁移中的Down()方法很有趣,因为当初始迁移中的CREATE TABLE似乎设置它时,它似乎试图从列中删除IDENTITY!
此外,如果您使用Update-Database -Script
或Update-Database -Verbose
查看从这些AlterColumn
方法运行的sql,您将看到sql在Up
和中是相同的Down
,并且实际上什么都不做.IDENTITY保持不变(对于当前版本 - EF 6.0.2及更低版本) - 如我链接的前两个问题中所述.
我认为您应该删除额外迁移中的冗余代码,并暂时使用空迁移.您可以订阅/投票支持要解决的问题.
参考文献:
改变IDENTITY选项确实蹲下了
使用自定义迁移操作打开/关闭标识
我还尝试再次删除数据库,称为update-database,然后添加迁移.我最终得到了一个似乎没有改变任何东西的额外迁移(见下文)
基于以上细节,我认为你先做了最后一件事.如果Update database
之前运行Add-migration
,则不会使用迁移模式更新数据库.首先,您需要添加迁移,然后运行update命令.
使用包管理器控制台按此顺序尝试它们.
PM> Enable-migrations //You don't need this as you have already done it PM> Add-migration Give_it_a_name PM> Update-database