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.