La mise à jour de la base de données Entity Framework Migration a réussi mais la colonne de base de données n'est pas ajoutée

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

Question

J'utilise Entity Framework dans VS2012 avec SQL Server 2008 R2.J'ai activé la migration et j'ajoute un champ de chaîne (c.-à-d.DropboxUrl) vers l'une de mes classes de base de données (c.-à-d.Dessins).

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

Dans Package Manager Console, lorsque j'exécute PM> Mise à jour-database, il se plaint qu'il existe déjà un objet nommé «Companies» dans la base de données.« Entreprises » est un tableau qui existe actuellement dans la base de données existante que j'essaie de mettre à jour.

c'est à dire.

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.

Tentative 1 : Après avoir recherché cette erreur, je suis tombé sur cette solution de contournement :http://christesene.com/entity-framework-4-3-code-first-with-automatic-migrations/

Il m'a recommandé de courir en premier

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.

Et supprimé la méthode Up/Down :

c'est à dire.J'ai pu voir que DropboxUrl était un champ dans la méthode Up mais je l'ai supprimé comme suggéré.

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

Ensuite, j'exécute à nouveau update-database et cela semble réussir.

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

Problème 1 : Ma table n'a pas été modifiée après la mise à jour (c.-à-d.la colonne DropboxUrl présente dans le code n'a pas été ajoutée à la base de données).

Problème 2 : Et je n'ai pas non plus pu remettre la base de données à son état initial :

c'est à dire.

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.

Tentative 2 : J'ai également essayé d'utiliser l'indicateur -IgnoreChanges lorsque j'ajoute une migration :Migrations automatiques pour ASP.NET SimpleMembershipProvider

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

PM> update-database -verbose

Encore une fois, j'ai vu la même chose, où la mise à jour de la base de données réussit mais la colonne de base de données DropboxUrl n'a pas été ajoutée à la table Designs.Cependant, si je crée une nouvelle base de données, la colonne DropboxUrl est présente comme prévu.

Question: Comment puis-je contourner le fait qu'il y a déjà un objet nommé « Entreprises » dans l'erreur de base de données lors de la mise à jour de la base de données, tout en ajoutant ma colonne avec succès ?Il semble que cela devrait être un scénario de base qui fonctionne.

Merci.

Était-ce utile?

La solution

Lorsque vous avez commenté les méthodes Up() et Down() lors de la migration, vous avez supprimé le code pour ajouter la colonne de base de données.

Vous devez modifier Up() et Down() comme suit pour votre initiale :

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

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

Pour qu'Entity Framework comprenne cela pour vous à l'avenir, vous devez effectuer une migration initiale pour lui faire comprendre qu'il existe une table existante. avant d'ajouter la propriété au code.par exemple. Add-Migration -force -ignore.

Ensuite, vous ajoutez la colonne et c'est parti Add-Migration AddedDropboxUrlColumn, et il générera les méthodes Up() et Down() comme je l'ai décrit dans une nouvelle migration.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top