O banco de dados de atualização da migração do Entity Framework foi bem-sucedido, mas a coluna do banco de dados não foi adicionada

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

Pergunta

Estou usando o Entity Framework no VS2012 com SQL Server 2008 R2.Tenho a migração habilitada e estou adicionando um campo de string (ou seja,DropboxUrl) para uma das minhas classes de banco de dados (ou seja.Projetos).

// 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);

No Console do Gerenciador de Pacotes, quando eu corro PM> Update-Database, ele reclama que já existe um objeto chamado 'empresas' no banco de dados.'Empresas' é uma tabela que existe atualmente no banco de dados existente que estou tentando atualizar.

ou seja.

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.

Tentativa 1: Depois de procurar esse erro, me deparei com esta solução alternativa:http://christesene.com/entity-framework-4-3-code-first-with-automatic-migrations/

Recomendou que eu corresse primeiro

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.

E removeu o método Up/Down:

ou seja.Pude ver que DropboxUrl era um campo no método Up, mas o removi conforme sugerido.

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);
*/
        }

Depois, executo update-database novamente e parece ter sido bem-sucedido.

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

Problema 1: Minha tabela não foi alterada após a atualização (ou seja.a coluna DropboxUrl que está presente no código não foi adicionada ao banco de dados).

Edição 2: E também não consegui fazer o banco de dados voltar ao estado inicial:

ou seja.

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.

Tentativa 2: Também tentei usar o sinalizador -IgnoreChanges ao adicionar a migração:Migrações automáticas para ASP.NET SimpleMembershipProvider

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

PM> update-database -verbose

Novamente, vi a mesma coisa, onde o banco de dados de atualização foi bem-sucedido, mas a coluna do banco de dados DropboxUrl não foi adicionada à tabela Designs.No entanto, se eu criar um novo banco de dados, a coluna DropboxUrl estará presente conforme o esperado.

Pergunta: Como eu poderia contornar o erro de que já existe um objeto chamado 'Empresas' no banco de dados ao atualizar o banco de dados e ainda adicionar minha coluna com êxito?Parece que deveria ser um cenário básico que simplesmente funciona.

Obrigado.

Foi útil?

Solução

Ao comentar os métodos Up() e Down() na migração, você removeu o código para adicionar a coluna do banco de dados.

Você deve alterar Up() e Down() da seguinte forma para sua inicial:

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

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

Para que o Entity Framework descubra isso para você no futuro, você precisa fazer uma migração inicial para entender que existe uma tabela antes de adicionar a propriedade ao código.por exemplo. Add-Migration -force -ignore.

Então você adiciona a coluna e vai Add-Migration AddedDropboxUrlColumn, e irá gerar os métodos Up() e Down() conforme descrevi em uma nova migração.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top