Déboguer les codes de migration Entity Framework en commençant par le code

138

J'utilise d'abord le code Entity Framework sur mon site Web et je me demande simplement s'il existe un moyen de déboguer les codes de migration. Vous savez, comme définir des points d'arrêt et des trucs comme ça.

J'utilise la console du gestionnaire de package pour mettre à jour la base de données en utilisant Update-Database.

Merci

Daniel
la source
C'est juste du code C # standard - donc oui, bien sûr, vous pouvez y définir des points d'arrêt .....
marc_s
1
mais l'application ne fonctionne pas réellement depuis que j'utilise la console du gestionnaire de package.
Daniel
1
Ensuite, ne procédez pas à la mise à niveau à partir de la console du gestionnaire de package, mais définissez l'initialiseur de migration comme initialiseur par défaut afin que la base de données soit migrée la première fois que votre application s'y connecte.
Wiktor Zychla
Je mets à jour ma base de données à l'aide du code de migration et je ne peux pas arrêter l'application et l'exécuter à nouveau pour exécuter l'initialiseur.
Daniel
La raison pour laquelle je n'utilise pas SQL est que le code de la mise à jour est plutôt compliqué et qu'il est presque impossible de l'implémenter en utilisant SQL.
Daniel

Réponses:

255

Je sais que EF Code First Migrations est un outil relativement nouveau, mais n'oubliez pas que vous êtes toujours dans .NET.

Vous pouvez donc utiliser:

if (System.Diagnostics.Debugger.IsAttached == false)
{
    System.Diagnostics.Debugger.Launch();
}

Après cela, vous pouvez voir votre InnerException.

Ou vous pouvez utiliser l'instruction try ... catch comme ceci: Gestion des exceptions Entity Framework

m_david
la source
3
Oui, cela fonctionne lors de l'exécution d'une base de données de mise à jour via la console du gestionnaire de packages. Très utile!
Tom Ferguson
11
J'ai ajouté ceci en haut de ma méthode Configuration.Seed. Cela provoque une fenêtre contextuelle qui vous permet de sélectionner votre Visual Studio pour déboguer le code. Cependant, mon système se bloque lorsque je le sélectionne (peut-être sans rapport avec lui).
Talon
3
Où mettre ce morceau de code? si quelqu'un peut aider! Merci.
Aritra B
4
Dans le constructeur de votre classe de configuration.
Casey
5
@Talon Go prenez un café et au moment où vous êtes de retour, une autre instance de Visual Studio est probablement apparue. :)
Corstian Boerman
11

Pour atteindre un point d'arrêt dans une migration de base de données, définissez le contexte sur MigrateDatabaseToLatestVersion lors de l'initialisation.

Database.SetInitializer(new MigrateDatabaseToLatestVersion<EnterContextHere, Configuration>());

Ensuite, vous déboguez simplement comme d'habitude (exécutez en utilisant f5) et le point d'arrêt atteindra la première fois que vous exécuterez le projet.

Le problème maintenant est que si vous déboguez une deuxième fois, la migration ne s'exécutera pas. En effet, la table __MigrationHistory a été mise à jour pour indiquer que vous avez migré vers la dernière version. Pour retester la migration, ouvrez la console du gestionnaire de packages et rétrogradez à la migration précédente:

Update-Database TargetMigration: ThePreviousMigrationName
robasaurus
la source
8

Ma réponse est peut-être un peu idiote, mais de toute façon, la voici. Si, comme moi, vous rencontrez parfois des problèmes avec la méthode Seed (), ce que je fais habituellement est simplement de créer une méthode publique qui appelle Protect Seed ().

public void SeedDebug(AppDbContext context)
{
    Seed(context);
}

puis dans mon HomeController j'appelle cette méthode en mode Debug.

public class HomeController : Controller
{
    var appDb = new AppDbContext();
    public ActionResult Index()
    {
        var config = new Configuration();
        config.SeedDebug(appDb);
        return View();
    }
}

Je sais que c'est une solution un peu boiteuse, mais c'est simple et rapide. Bien sûr, cela doit être fait après la création du modèle. Donc étape par étape:

  1. commentez la méthode seed et exécutez la update-database pour créer le modèle
  2. décommentez la méthode Seed () et le plugin "hack" que j'ai mentionné plus haut.

  3. dans la configuration désactiver les migrations automatiques

    AutomaticMigrationsEnabled = false; // si vous avez déjà désactivé cette étape, sautez cette étape

  4. Déboguez votre application, corrigez l'erreur et supprimez le "hack"

Rui Lima
la source
5

Voici une méthode plus infaillible qui fera l'affaire sans trop d'histoires:

Étape # 1: placez ce morceau de code juste au-dessus de la migration que vous souhaitez déboguer:

public partial class ORACLE_Test : DbMigration
{
    public override void Up()
    {
        if (!System.Diagnostics.Debugger.IsAttached)
            System.Diagnostics.Debugger.Launch();

        AddColumn("TEST", "UR_USER_ID", x => x.Decimal(nullable: false, precision: 11, scale: 0, storeType: "number"));
        AddColumn("TEST", "UR_CLIENT_ID", x => x.Decimal(nullable: false, precision: 11, scale: 0, storeType: "number"));
        [...]
    }

    public override void Down()
    {
    }
}

Étape # 2: compilez le projet contenant vos migrations

Étape # 3: Ouvrez une console dans le répertoire de sortie (/ bin / Debug, / bin / Release etc) contenant la dll de vos migrations

Étape # 4: Appelez migrate.exe avec le paramètre / scriptFile pour lancer le débogueur et déboguer réellement la migration de base de données souhaitée

migrate.exe "Your.Migrations.Assembly.dll" /scriptFile="foo.sql" /verbose /startupConfigurationFile="Your.Migrations.Assembly.config"

Une fois que la boîte de dialogue de sélection du débogueur apparaît, choisissez l'instance de Visual Studio que vous avez déjà ouverte.

XDS
la source
4

Vous pouvez ajouter des instructions Console.WriteLine au code de migration (ce n'est pas une excellente solution)

Notez que les messages ne s'affichent que si vous exécutez le code de migration à l'aide de l' migrate.exeutilitaire (in pacakges\EntityFramework.x.y.z\tools). Ils ne s'afficheront pas si vous exécutez la migration via la console du gestionnaire de package.

Tom Ferguson
la source
Merci Tom ... C'était la réponse la plus proche que je pouvais obtenir. Si personne ne répond à cela avec une meilleure solution, je vais la marquer comme réponse. :)
Daniel
Ou lancez une exception avec votre message que vous souhaitez renvoyer.
David d C e Freitas
2

J'ai eu beaucoup de chance en utilisant "Debugger.Launch ()" (comme dans la réponse de m_david ci-dessus ) ailleurs, mais à l'intérieur de CreateDbContext, il semble à la fois attacher et non attacher. Ce que je veux dire, c'est qu'il s'attache et commence à essayer d'entrer dans les fichiers .asm et .cpp (code interne). Si j'essaye de placer un point d'arrêt sur un Console.Writeline que JE SAIS est exécuté après (je peux voir la sortie de N'IMPORTE QUELLE "COMMANDE de migrations de dotnet ef") il l'exécute et ne frappe jamais le point d'arrêt.

C'est ce qui a fonctionné pour moi à la place:

while (!System.Diagnostics.Debugger.IsAttached)
    System.Threading.Thread.Sleep(10);

// Breakpoint after this...

Vous pouvez exécuter la migration et l'attacher manuellement à l'aide de Visual Studio et cela vous permettra en fait de parcourir le code comme prévu, c'est juste plus pénible. Ce que je devrais vraiment essayer, c'est la combinaison des deux méthodes ...

Brent Rittenhouse
la source
À quel processus vous attachez-vous?
XDS
-1

J'ai également trouvé une astuce intéressante ici pour obtenir les détails de l'erreur ...

Fondamentalement, l'astuce consiste à récupérer toutes les informations d'une exception, à les mettre dans une chaîne et à lancer une nouvelle exception DbEntityValidationException avec la chaîne générée et l'exception d'origine.

ghigad
la source