Primero depurar códigos de migración de Entity Framework

138

Estoy usando el código de Entity Framework primero en mi sitio web y me pregunto si hay alguna forma de depurar los códigos de migración. Ya sabes, como establecer puntos de interrupción y cosas como esta.

Estoy usando Package Manager Console para actualizar la base de datos usando Update-Database.

Gracias

Daniel
fuente
Es simplemente el código estándar de C # - así que sí, por supuesto, se puede establecer puntos de interrupción en ella .....
marc_s
1
pero la aplicación no se está ejecutando realmente porque estoy usando Package Manager Console.
Daniel
1
Luego, no actualice desde la consola del Administrador de paquetes, pero configure el inicializador de migración como el inicializador predeterminado para que la base de datos se mitigue la primera vez que su aplicación se conecte a ella.
Wiktor Zychla
Estoy actualizando mi base de datos usando el código de migración y no puedo detener la aplicación y ejecutarla nuevamente para ejecutar el inicializador.
Daniel
La razón por la que no estoy usando SQL es que el código para la actualización es bastante complicado y es casi imposible implementarlo usando SQL.
Daniel

Respuestas:

255

Sé que EF Code First Migrations es una herramienta relativamente nueva, pero no olvides que todavía estás en .NET.

Entonces puedes usar:

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

Después de eso, puede ver su InnerException.

O puede usar la declaración try ... catch de esta manera: Manejo de excepciones Entity Framework

m_david
fuente
3
Sí, esto funciona mientras se ejecuta una base de datos de actualización a través de la consola del administrador de paquetes. ¡Muy útil!
Tom Ferguson
11
Agregué esto a la parte superior de mi método Configuration.Seed. Causa una ventana emergente que le permite seleccionar su Visual Studio para depurar el código. Sin embargo, mi sistema se bloquea cuando lo selecciono (tal vez no relacionado).
Talon
3
¿Dónde poner esta pieza de código? si alguien puede ayudar! Gracias.
Aritra B
44
En el constructor de su clase de configuración.
Casey
55
@Talon Go toma un café y para cuando vuelvas probablemente haya aparecido otra instancia de Visual Studio. :)
Corstian Boerman
11

Para alcanzar un punto de interrupción en una migración de base de datos, establezca el contexto en MigrateDatabaseToLatestVersion al inicializar.

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

Luego, simplemente depura normalmente (ejecuta usando f5) y el punto de interrupción llegará la primera vez que ejecutes el proyecto.

El problema ahora es que si depura por segunda vez la migración no se ejecutará. Esto se debe a que la tabla __MigrationHistory se ha actualizado para indicar que ha migrado a la última versión. Para volver a probar la migración, abra la consola del administrador de paquetes y baje a la migración anterior:

Update-Database TargetMigration: ThePreviousMigrationName
robasaurus
fuente
8

Mi respuesta puede ser un poco tonta, pero de todos modos aquí va. Si, como yo, algunas veces tiene problemas con el método Seed (), lo que suelo hacer es crear un método público que llame a Protect Seed ().

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

luego en mi HomeController llamo a este método en modo de depuración.

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

Sé que es una solución poco convincente, pero es simple y rápida. Por supuesto, esto debe hacerse después de que se haya creado el modelo. Entonces paso a paso:

  1. comentar el método de inicialización y ejecutar la base de datos de actualización para crear el modelo
  2. descomente el método Seed () y agregue el "hack" que mencioné anteriormente.

  3. en la configuración deshabilitar las migraciones automáticas

    AutomaticMigrationsEnabled = false; // si tiene esto desactivado, omita este paso

  4. Depure su aplicación, corrija el error y elimine el "hack"

Rui Lima
fuente
5

Aquí hay un método más a prueba de fallas que hará el truco sin mucho alboroto:

Paso 1: coloque este fragmento de código justo encima de la migración que desea depurar:

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()
    {
    }
}

Paso # 2: compila el proyecto que contiene tus migraciones

Paso 3: abra una consola dentro del directorio de salida (/ bin / Debug, / bin / Release, etc.) que contiene el dll de sus migraciones

Paso 4: invoque migrate.exe con el parámetro / scriptFile para iniciar el depurador y realmente depurar la migración de db deseada

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

Una vez que aparezca el cuadro de diálogo del selector de depurador, elija la instancia de Visual Studio que ya ha abierto.

XDS
fuente
4

Puede agregar instrucciones Console.WriteLine al código de migración (no es una gran solución)

Tenga en cuenta que los mensajes solo se muestran si ejecuta el código de migración utilizando la migrate.exeutilidad (in pacakges\EntityFramework.x.y.z\tools). No se mostrarán si ejecuta la migración a través de la consola de Package Manager.

Tom Ferguson
fuente
Gracias Tom ... Fue la respuesta más cercana que pude obtener. Si nadie responde esto con una mejor solución, lo marcaré como respuesta. :)
Daniel
O lanzar una excepción con su mensaje que desea devolver.
David d C e Freitas
2

He tenido mucha suerte usando "Debugger.Launch ()" (como en la respuesta de m_david anterior ) en otro lugar, pero dentro de CreateDbContext parece de alguna manera adjuntar, y no adjuntar. Lo que quiero decir es que se adjunta y comienza a intentar ingresar a archivos .asm y archivos .cpp (código interno). Si trato de establecer un punto de interrupción en una consola. La línea de escritura que sé que se ejecuta después (puedo ver el resultado de CUALQUIER "comando de migraciones de dotnet ef") lo ejecuta y nunca llega al punto de interrupción.

Esto es lo que funcionó para mí en su lugar:

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

// Breakpoint after this...

Puede ejecutar la migración y adjuntarla manualmente con Visual Studio y , de hecho, le permitirá recorrer el código como esperaba, es simplemente más doloroso. Lo que realmente debería probar es la combinación de ambos métodos ...

Brent Rittenhouse
fuente
¿A qué proceso te estás apegando?
XDS
-1

También encontré un buen truco aquí para obtener los detalles del error ...

Básicamente, el truco consiste en obtener toda la información de una excepción, ponerla en una cadena y lanzar una nueva DbEntityValidationException con la cadena generada y la excepción original.

ghigad
fuente