我在 VS2012 中使用实体框架和 SQL Server 2008 R2。我启用了迁移,并且添加了一个字符串字段(即DropboxUrl)到我的数据库类之一(即设计)。

// Design.cs

public class Design
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public Guid Id { get; set; }

        [StringLength(Constants.DESIGN_NAME_MAX_LENGTH)]
        public string Name { get; set; }

        [StringLength(Constants.DESIGN_DESC_MAX_LENGTH)]
        public string Description { get; set; }

        public ItemDate Dates { get; set; }

        public string DropboxUrl { get; set; } // Added this line
    }

// SedaContext.cs:

public class SedaContext : DbContext
    {
        public DbSet<Company> Companies { get; set; }

        public DbSet<Design> Designs { get; set; }
…
}


// Global.aspx
protected void Application_Start()
        {

            // Application initialize
            // https://stackoverflow.com/questions/3600175/the-model-backing-the-database-context-has-changed-since-the-database-was-crea

            Database.SetInitializer<SedaContext>(null);

在包装管理器控制台中,当我运行PM>“ Update-Database”时,它抱怨数据库中已经有一个名为“公司”的对象。“公司”是我正在尝试更新的现有数据库中当前存在的表。

IE。

PM> update-database -verbose
Using StartUp project 'UI'.
Using NuGet project 'UI'.
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Target database is: 'SedaDev' (DataSource: ., Provider: System.Data.SqlClient, Origin: Configuration).
No pending explicit migrations.
Applying automatic migration: 201405311730564_AutomaticMigration.
CREATE TABLE [dbo].[Companies] (
    [Id] [uniqueidentifier] NOT NULL DEFAULT newsequentialid(),
    [Name] [nvarchar](max),
    [Description] [nvarchar](max),
    [Owner_UserId] [int],
    CONSTRAINT [PK_dbo.Companies] PRIMARY KEY ([Id])
)
System.Data.SqlClient.SqlException (0x80131904): There is already an object named 'Companies' in the database.
...
   at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
   at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run()
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force)
   at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
   at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
ClientConnectionId:fa9e9e62-aba0-435f-9309-e9fc8fbe19d5

There is already an object named 'Companies' in the database.

尝试1: 搜索此错误后,我遇到了以下解决方法:http://christesene.com/entity-framework-4-3-code-first-with-automatic-migrations/

建议我先跑

PM> Add-migration initial

Scaffolding migration 'initial'.
The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration initial' again.

并删除了 Up/Down 方法:

IE。我可以看到 DropboxUrl 是 Up 方法中的一个字段,但我按照建议将其删除。

public override void Up()
        {
/*
    CreateTable(
                "dbo.Companies",
                c => new
                    {
                        Id = c.Guid(nullable: false, identity: true),
                        Name = c.String(),
                        Description = c.String(),
                        Owner_UserId = c.Int(),
                    })
                .PrimaryKey(t => t.Id)
                .ForeignKey("dbo.UserProfiles", t => t.Owner_UserId)
                .Index(t => t.Owner_UserId);
...
  CreateTable(                "dbo.Designs",
                c => new
                    {
                        Id = c.Guid(nullable: false, identity: true),
                        Name = c.String(maxLength: 100),
                        Description = c.String(maxLength: 1000),
                        Dates_Create = c.DateTime(nullable: false),
                        Dates_LastUpdate = c.DateTime(nullable: false),
                        DropboxUrl = c.String(),
                        Project_Id = c.Guid(),
                    })
                .PrimaryKey(t => t.Id)
                .ForeignKey("dbo.Projects", t => t.Project_Id)
                .Index(t => t.Project_Id);
*/
        }

之后,我再次运行 update-database,似乎成功了。

PM> update-database -verbose
Using StartUp project 'UI'.
Using NuGet project 'UI'.
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Target database is: 'SedaDev' (DataSource: phobos.spxis.com, Provider: System.Data.SqlClient, Origin: Configuration).
Applying explicit migrations: [201406020449030_initial].
Applying explicit migration: 201406020449030_initial.
INSERT [dbo].[__MigrationHistory]([MigrationId], [ContextKey], [Model], [ProductVersion])

VALUES (N'201406020449030_initial', N'Delecs.Seda.DataAccess.Migrations.Configuration',  0x1F8B0800000000000400ED1DCB72DCB8F19EAAFCC3D49C92544523D9F166
...
7B7C117028FAD9D8632C54E5F87C13A0D36590D83B7A73FA9F8AD368F7FFE3F0347EA807B340100 , N'6.0.2-21211')
Running Seed method

问题一: 更新后我的表没有改变(即代码中存在的 DropboxUrl 列未添加到数据库中)。

问题2: 而且我也无法将数据库恢复到其初始状态:

IE。

PM> update-database -TargetMigration $InitialDatabase
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Reverting migrations: [201406020449030_initial].
Reverting automatic migration: 201406020449030_initial.
Automatic migration was not applied because it would result in data loss.
PM> update-database -TargetMigration $InitialDatabase -force
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Reverting migrations: [201406020449030_initial].
Reverting automatic migration: 201406020449030_initial.
System.Data.SqlClient.SqlException (0x80131904): Could not drop object 'dbo.UserProfiles' because it is referenced by a FOREIGN KEY constraint.

尝试2: 我还尝试在添加迁移时使用 -IgnoreChanges 标志:ASP.NET SimpleMembershipProvider 自动迁移

PM> Add-migration initial -IgnoreChanges
Re-scaffolding migration 'initial'.

PM> update-database -verbose

我再次看到同样的事情,更新数据库成功,但数据库列 DropboxUrl 未添加到 Designs 表中。但是,如果我创建一个新数据库,则 DropboxUrl 列将按预期显示。

问题: 在执行更新数据库时,如何解决数据库中已有一个名为“公司”的对象错误,并仍然成功添加我的列?看起来这应该是一个可以正常工作的基本场景。

谢谢。

有帮助吗?

解决方案

当您注释掉迁移中的 Up() 和 Down() 方法时,您删除了添加数据库列的代码。

您应该按如下方式更改您的初始值的 Up() 和 Down() :

public override void Up() {
   AddColumn("Companies", "DropboxUrl", x => x.String());
}

public override void Down() {
    DropColumn("Companies", "DropboxUrl");
}

为了让实体框架将来为您解决这个问题,您需要进行初始迁移以使其了解存在一个现有表 在将属性添加到代码之前. 。例如 Add-Migration -force -ignore.

然后添加列并继续 Add-Migration AddedDropboxUrlColumn, ,它将生成 Up() 和 Down() 方法,正如我在新迁移中所描述的那样。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top