Códigos de migração do primeiro código de depuração do Entity Framework


138

Estou usando o código do Entity Framework primeiro no meu site e estou me perguntando se existe alguma maneira de depurar os códigos de migração. Você sabe, como definir pontos de interrupção e coisas assim.

Estou usando o Package Manager Console para atualizar o banco de dados usando Update-Database.

obrigado


É o código apenas padrão C # - então sim, é claro, você pode definir pontos de interrupção em que .....
— marc_s

1
mas o aplicativo não está em execução, pois estou usando o Package Manager Console.
— Daniel

1
Em seguida, não atualize a partir do console do gerenciador de pacotes, mas defina o inicializador de migração como inicializador padrão para que o banco de dados seja migrado na primeira vez que seu aplicativo se conectar a ele.
— Wiktor Zychla

Estou atualizando meu banco de dados usando o código de migração e não consigo parar o aplicativo e executá-lo novamente para executar o inicializador.
— 18713 Daniel

A razão pela qual não estou usando SQL é o código para a atualização é bastante complicado e é quase impossível implementá-lo usando SQL.
— 18713 Daniel

Respostas:


255

Eu sei que a EF Code First Migrations é uma ferramenta relativamente nova, mas não esqueça que você ainda está no .NET.

Então você pode usar:

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

Depois disso, você pode ver sua InnerException.

Ou você pode usar a instrução try ... catch como esta: Exceção ao lidar com o Entity Framework


3
Sim, isso funciona durante a execução de um banco de dados de atualização no console do gerenciador de pacotes. Muito conveniente!
— Tom Ferguson

11
Adicionei isso ao topo do meu método Configuration.Seed. Isso causa um pop-up que permite selecionar o Visual Studio para depurar o código. No entanto, meu sistema trava quando eu o seleciono (talvez não relacionado).
— Talon

3
Onde colocar esse pedaço de código? se alguém puder ajudar! Obrigado.
— Aritra B

4
No construtor da sua classe de configuração.
— Casey #

5
@Talon Vá tomar um café e quando voltar, provavelmente outra instância do Visual Studio apareceu. :)
— Corstian Boerman

11

Para atingir um ponto de interrupção em uma migração de banco de dados, defina o contexto como MigrateDatabaseToLatestVersion na inicialização.

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

Então você apenas depura normalmente (execute usando f5) e o ponto de interrupção será atingido na primeira vez em que o projeto for executado.

O problema agora é que, se você depurar uma segunda vez, a migração não será executada. Isso ocorre porque a tabela __MigrationHistory foi atualizada para dizer que você migrou para a versão mais recente. Para testar novamente a migração, abra o console do gerenciador de pacotes e faça o downgrade para a migração anterior:

Update-Database –TargetMigration: ThePreviousMigrationName

8

Minha resposta pode ser um pouco boba, mas mesmo assim aqui vai. Se você, como eu, algumas vezes tem problemas no método Seed (), o que eu costumo fazer é simplesmente criar um método público que chama Protect Seed ().

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

então, no meu HomeController, chamo esse método no modo de depuração.

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

Eu sei que é uma solução um pouco esfarrapada, mas é simples e rápida. Obviamente, isso deve ser feito após a criação do modelo. Então, passo a passo:

  1. comente o método seed e execute o banco de dados de atualização para criar o modelo
  2. descomente o método Seed () e conecte o "hack" que mencionei acima.

  3. na configuração, desative Migrações automáticas

    AutomaticMigrationsEnabled = false; // se você tiver esse desativado, pule esta etapa

  4. Depure seu aplicativo, corrija o erro e remova o "hack"


5

Aqui está um método mais à prova de falhas que fará o truque sem muito barulho:

Etapa 1: coloque esse trecho de código logo acima da migração que você deseja 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()
    {
    }
}

Etapa 2: compilar o projeto que contém suas migrações

Etapa 3: abra um console dentro do diretório de saída (/ bin / Debug, / bin / Release etc) contendo a dll de suas migrações

Etapa # 4: Invoque migrate.exe com o parâmetro / scriptFile para iniciar o depurador e depurar o db-migration desejado

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

Depois que a caixa de diálogo seletor de depurador aparecer, escolha a instância do visual studio que você já abriu.


4

Você pode adicionar instruções Console.WriteLine ao código de migração (não é uma ótima solução)

Observe que as mensagens são mostradas apenas se você executar o código de migração usando o migrate.exeutilitário (in pacakges\EntityFramework.x.y.z\tools). Eles não serão exibidos se você executar a migração pelo console do Package Manager.


Obrigado Tom ... Foi a resposta mais próxima que pude obter. Se ninguém responder isso com uma solução melhor, vou marcar como resposta. :)
— Daniel

Ou lance uma exceção com sua mensagem que você deseja retornar.
— David d C e Freitas

2

Eu tive muita sorte usando "Debugger.Launch ()" (como na resposta de m_david acima ) em outro lugar, mas dentro do CreateDbContext parece de alguma forma ambos anexar e não anexar. O que quero dizer é que ele anexa e começa a tentar entrar nos arquivos .asm e .cpp (código interno). Se eu tentar definir um ponto de interrupção em um Console.Writeline que SEI executado depois (eu posso ver a saída de QUALQUER "dotnet ef migrations COMMAND"), ele o executa e nunca atinge o ponto de interrupção.

Isto é o que funcionou para mim:

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

// Breakpoint after this...

Você pode executar a migração e manualmente anexar usando o Visual Studio e ele vai realmente deixá-lo percorrer o código como você espera, é apenas mais uma dor. O que eu realmente deveria tentar é a combinação dos dois métodos ...


A qual processo você está se conectando?
— XDS

-1

Também encontrei um truque legal aqui para obter os detalhes do erro ...

Basicamente, o truque é pegar todas as informações de uma exceção, colocá-las em uma string e lançar uma nova DbEntityValidationException com a string gerada e a exceção original.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.