web-dev-qa-db-fra.com

Modifier les données dans la méthode de migration Up - Entity Framework

J'ai ajouté une nouvelle propriété à mon modèle existant. C'est une propriété bool avec la valeur par défaut true. Il y a des données existantes dans ce tableau et je voudrais définir la nouvelle propriété d'une ligne spécifique sur false juste après avoir créé le nouveau champ, dans la méthode Up.

public override void Up()
    {
        AddColumn("dbo.RequestValidationErrors", "IsBreaking", c => c.Boolean(nullable: false));
        using (Context ctx = new Context())
        {
            var validation = ctx.RequestValidationErrorSet.FirstOrDefault(x => x.WordCode == "RequestValidationError.MoreThanOneItemFound");
            if (validation != null)
            {
                validation.IsBreaking = false;
                ctx.SaveChanges();
            }
        }
    }

De cette façon, EF lance une erreur lors de la déclaration

System.InvalidOperationException: le modèle soutenant le contexte 'DbContext' a changé depuis la création de la base de données. Envisagez d'utiliser Code First Migrations pour mettre à jour la base de données

Est-il possible de changer la base de données ici ou dois-je le faire ailleurs?

38
Perrier

Au milieu d'une migration, il est préférable d'utiliser la méthode Sql() pour mettre à jour les données de la base de données.

Sql("UPDATE dbo.RequestValidationErrors SET IsBreaking = 0 WHERE WordCode = 'RequestValidationError.MoreThanOneItemFound'");

Vous devez également définir la valeur par défaut de la nouvelle colonne. La solution devrait donc être quelque chose comme ceci:

public override void Up()
{
    AddColumn("dbo.RequestValidationErrors", "IsBreaking", c => c.Boolean(nullable: false, default: true));
    Sql("UPDATE dbo.RequestValidationErrors SET IsBreaking = 0 WHERE WordCode = \"RequestValidationError.MoreThanOneItemFound\"");
}

L'utilisation d'un DbContext au milieu de sa migration est très ambiguë. Qu'attendez-vous du contexte? Il a après l'état de migration dans ses modèles, mais la base de données a avant l'état de migration dans les tableaux. Le modèle et la base de données ne correspondent donc pas. Si vous persistez à utiliser DbContext dans votre code, la désactivation de la vérification des modèles pourrait être la solution. Vous pouvez désactiver la vérification des modèles à l'aide de:

Database.SetInitializer<Log4ProContext>(null);
47
mehrandvd

Si vous souhaitez utiliser le cadre pour des modifications comme celle-ci, vous devez séparer les modifications de la base de données des modifications des données.

Créez une migration uniquement pour les modifications de la base de données et exécutez.

Créez ensuite une nouvelle migration (les méthodes Up () et Down () seront vides). Vous pouvez maintenant instancier votre DatabaseContext et il n'y aura aucune erreur. De cette façon, vous pouvez utiliser le Framework pour ces modifications et implémenter correctement une méthode Down ().

16
user868386

Au lieu d'utiliser la méthode Sql, vous pouvez également utiliser la méthode UpdateData .

migrationBuilder.UpdateData(
    table: "RequestValidationErrors", 
    keyColumn: "WordCode", 
    keyValue: "RequestValidationError.MoreThanOneItemFound", 
    column: "IsBreaking", 
    value: false);

(Je ne sais pas si seul le noyau ef prend en charge cette méthode)

8
NtFreX

L'écriture de DataMigrations pour EF6 peut être une corvée. Nous avons mis en place une bibliothèque que je suis juste open source ici pour les autres à utiliser, qui ajoute cette fonctionnalité manquante promise depuis longtemps à EF6. Écrivez simplement des classes en utilisant des requêtes EF régulières, etc.

https://github.com/b9chris/Brass9.Data

2
Chris Moschini