web-dev-qa-db-fra.com

Comment renommer une colonne de base de données dans les migrations Entity Framework 5 Code First sans perdre de données?

J'ai obtenu le modèle ASP.NET MVC 4 par défaut en cours d'exécution avec succès avec EF 5.0 Code First Migrations. Cependant, lorsque je mets à jour un nom de propriété de modèle, les données de colonne de table correspondantes sont supprimées par EF 5.0.

Est-il possible de renommer la colonne de la table sans perdre de données de manière automatisée?

68
Dante

Modifiez manuellement les méthodes Haut et Bas de la migration pour utiliser la méthode RenameColumn pour remplacer les AddColumn et DropColumn qu'elle génère automatiquement pour vous.

106
Josh Gallagher

Comme déjà dit , remplacez les AddColumn et DropColumn qui sont générés automatiquement par RenameColumn.

Exemple:

namespace MyProject.Model.Migrations
{
    using System;
    using System.Data.Entity.Migrations;

    public partial class RenameMyColumn : DbMigration
    {
        public override void Up()
        {
            // Remove the following auto-generated lines
            AddColumn("dbo.MyTable", "NewColumn", c => c.String(nullable: false, maxLength: 50));
            DropColumn("dbo.MyTable", "OldColumn");

            // Add this line
            RenameColumn("dbo.MyTable", "OldColumn", "NewColumn");
        }

        public override void Down()
        {
            // Remove the following auto-generated lines
            AddColumn("dbo.MyTable", "OldColumn", c => c.String(nullable: false, maxLength: 50));
            DropColumn("dbo.MyTable", "NewColumn");

            // Add this line
            RenameColumn("dbo.MyTable", "NewColumn", "OldColumn");
        }
    }
}
42
Zanon

Vous pouvez obtenir la migration pour appeler RenameColumn pour vous si vous faites ceci:

[Column("NewName")]
public string OldName { get; set; }

Voici la migration générée:

    public override void Up()
    {
        RenameColumn(table: "Schema.MyTable", name: "OldName", newName: "NewName");
    }

    public override void Down()
    {
        RenameColumn(table: "Schema.MyTable", name: "NewName", newName: "OldName");
    }

Si vous souhaitez que votre propriété et votre colonne de base de données portent le même nom, vous pouvez renommer la propriété ultérieurement et supprimer l'attribut Column.

11
Jess

Maintenant, cette réponse est basée sur ma connaissance d'EF4.3, donc j'espère que les migrations fonctionneront à peu près de la même manière dans EF5 :) Après avoir créé une migration, vous devriez pouvoir ajouter du code dans les méthodes Up et Down, entre l'abandon de l'ancienne propriété et la création de la nouvelle propriété. Ce code doit déplacer les données de propriété dans la bonne direction. Je l'ai résolu avec la méthode SQL () dans laquelle vous pouvez entrer du SQL brut pour effectuer le déplacement des données.

Dans la méthode Up de la migration:

SQL("update [TheTable] set [NewColumn] = [OldColumn]");

et dans la méthode Down ():

SQL("update [TheTable] set [OldColumn] = [NewColumn]");

L'inconvénient de cette approche est que vous pouvez coupler votre code avec la base de données avec laquelle vous travaillez actuellement (puisque vous écrivez du SQL brut spécifique à la DB). D'autres méthodes peuvent également être disponibles pour le déplacement des données.

Plus d'informations disponibles ici: MSDN

4
Daniel Persson

Ajoutant à la réponse de Josh Gallagher:

À certains endroits, la syntaxe sp_RENAME est décrite comme suit:

sp_RENAME 'TableName.[OldColumnName]' , '[NewColumnName]', 'COLUMN'

Cependant, cela inclura en fait les crochets dans le nouveau nom de colonne.

La méthode RenameColumn () de DbMigration fera probablement de même, donc évitez d'utiliser des crochets lorsque vous spécifiez le nouveau nom de colonne.

De plus, les commandes générées automatiquement dans Up () et Down () incluent DropPrimaryKey () et AddPrimaryKey () si la colonne en cours de changement de nom fait partie de la clé primaire. Ceux-ci ne sont pas nécessaires lors de l'utilisation de RenameColumn (). Le sp_RENAME sous-jacent met automatiquement à jour la clé primaire si nécessaire.

3
jk7

vous avez 2 étapes pour renommer la colonne dans la première migration de code

  1. La première étape, vous ajoutez ColumnAttribute au-dessus de votre colonne qui sont modifiées, puis la commande update-database

[Colonne ("Contenu")]
chaîne publique Description {set; obtenir; }

  1. La deuxième étape,

    • commande add-migration yournamechange afin de créer une classe partielle DbMigration.

    • ajouter dans la méthode de haut en bas ici

RenameColumn ("yourDatabase", "name", "newName");

public override void Up()
  {
        RenameColumn("dbo.your_database", "oldColumn",          
       "newColumn");
  }


public override void Down()
  {
        RenameColumn("dbo.your_database", "newColumn", 
        "oldColumn");
  }

Parce que lorsque vous vous connectez, votre base de données et votre classe de modèle communiqueront via nom_colonne dans la base de données et nom_type dans la méthode de propriété dans le modèle ci-dessus.

3
Thảo Frederic

comme + Josh Gallagher l'a dit, vous pouvez utiliser up () pour faire des choses comme:

public override void Up()
        {

            RenameColumn("dbo.atable","odlanem","newname");
            AddColumn("dbo.anothertable", "columname", c => c.String(maxLength: 250));

        }

j'ai trouvé this une bonne aide pour entrer dans la migration;)

0
womd