Entity Framework の移行更新データベースは成功しましたが、データベース列が追加されませんでした

StackOverflow https://stackoverflow.com//questions/24007883

質問

SQL Server 2008 R2 を備えた VS2012 で Entity Framework を使用しています。移行を有効にし、文字列フィールドを追加しています(つまり、DropboxUrl) をデータベース クラスの 1 つ (つまり、.デザイン)。

// 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を実行すると、データベースに「会社」という名前のオブジェクトが既にあることに不満を述べています。「Companies」は、更新しようとしている既存のデータベースに現在存在するテーブルです。

つまり。

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 メソッドを削除しました。

つまり。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

問題 1: 私のテーブルは更新後に変更されませんでした(つまり、コード内に存在する DropboxUrl 列はデータベースに追加されませんでした)。

問題 2: また、データベースを初期状態に戻すこともできませんでした。

つまり。

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 列は期待どおりに存在します。

質問: update-database の実行中に「データベースに「Companies」という名前のオブジェクトがすでに存在します」というエラーを回避し、列を正常に追加するにはどうすればよいでしょうか?これは、機能する基本的なシナリオである必要があるようです。

ありがとう。

役に立ちましたか?

解決

移行時に Up() メソッドと Down() メソッドをコメントアウトしたときに、データベース列を追加するコードを削除しました。

最初の Up() と Down() を次のように変更する必要があります。

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

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

今後 Entity Framework がこれを認識できるようにするには、初期移行を実行して、既存のテーブルの存在を認識させる必要があります。 コードにプロパティを追加する前に. 。例えば Add-Migration -force -ignore.

次に、列を追加して実行します Add-Migration AddedDropboxUrlColumn, 新しい移行で説明したように、Up() メソッドと Down() メソッドが生成されます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top