Modifier les données dans la méthode de migration vers le haut-cadre de L'entité

j'ai ajouté une nouvelle propriété dans mon modèle existant. C'est une propriété bool avec une valeur par défaut true. Il y a des données existantes dans ce tableau et je voudrais mettre la nouvelle propriété d'une ligne spécifique à 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 en disant

Système.InvalidOperationException: le modèle Le contexte' DbContext ' a changé depuis la création de la base de données. Considérer utiliser les premières Migrations de Code pour mettre à jour la base de données

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

26
demandé sur Perrier 2015-11-04 11:09:17

4 réponses

au milieu d'une migration, il est préférable d'utiliser Sql() méthode de mise à jour 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 pour 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\"");
}

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

Database.SetInitializer<Log4ProContext>(null);
31
répondu mehrandvd 2015-11-04 08:36:37

si vous voulez utiliser le framework pour des changements comme celui-ci, vous devriez séparer les changements de base de données des changements de données.

créer une migration pour juste les changements de base de données, et exécuter.

puis créer une nouvelle migration (les méthodes Up() et Down() seront vides). Vous pouvez maintenant instancier votre DatabaseContext et il n'y aura pas d'erreur. De cette façon, vous pouvez utiliser le Framework pour ces changements, et implémenter correctement une méthode Down ().

11
répondu user868386 2016-08-17 18:06:00

écrire des migrations de données pour EF6 peut être une corvée. Nous avons mis en place une bibliothèque je suis juste open sourcing ici pour d'autres à utiliser, qui ajoute dans cette fonctionnalité longtemps promise, manquant à EF6. Il suffit d'écrire des classes en utilisant des requêtes EF régulières, etc.

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

2
répondu Chris Moschini 2017-05-20 18:08:43

au Lieu d'utiliser le Sql méthode vous pouvez également utiliser le UpdateData méthode.

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

(je ne sais pas si seulement ef de base prend en charge cette méthode)

1
répondu NtFreX 2018-04-11 14:18:16