Отладка кода миграции Entity Framework с первым кодом

140

Сначала я использую код Entity Framework на своем веб-сайте, и мне просто интересно, есть ли способ отладить коды миграции. Вы знаете, как установка точек останова и тому подобное.

Я использую консоль диспетчера пакетов для обновления базы данных с помощью Update-Database.

Благодарность

Даниэль
источник
Это просто стандартный код C # - так что да, конечно, вы можете установить в нем точки останова .....
marc_s
1
но приложение фактически не запущено, поскольку я использую консоль диспетчера пакетов.
Daniel
1
Затем не выполняйте обновление из консоли диспетчера пакетов, а установите инициализатор миграции в качестве инициализатора по умолчанию, чтобы база данных переносилась при первом подключении к ней вашего приложения.
Wiktor Zychla
Я обновляю свою базу данных с помощью кода миграции, и я не могу остановить приложение и снова запустить его, чтобы запустить инициализатор.
Daniel
Причина, по которой я не использую SQL, заключается в том, что код для обновления довольно сложен и практически невозможно реализовать с помощью SQL.
Daniel

Ответы:

258

Я знаю, что EF Code First Migrations - относительно новый инструмент, но не забывайте, что вы все еще используете .NET.

Итак, вы можете использовать:

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

После этого вы можете увидеть свое InnerException.

Или вы можете использовать оператор try ... catch, например: Обработка исключений Entity Framework

m_david
источник
3
Да, это работает при запуске Update-Database через консоль диспетчера пакетов. Очень удобно!
Tom Ferguson
11
Я добавил это в начало моего метода Configuration.Seed. Это вызывает всплывающее окно, в котором вы можете выбрать Visual Studio для отладки кода. Однако моя система зависает, когда я ее выбираю (возможно, не связанную).
Talon
3
Куда девать этот кусок кода? если кто может выручать! Спасибо.
Aritra B
4
В конструкторе вашего класса конфигурации.
Кейси
5
@Talon Go, возьмите кофе, и к тому времени, когда вы вернетесь, вероятно, появится другой экземпляр Visual Studio. :)
Corstian Boerman
11

Чтобы достичь точки останова в миграции базы данных, установите контекст в MigrateDatabaseToLatestVersion при инициализации.

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

Затем вы просто отлаживаете как обычно (запускаете с помощью f5), и точка останова сработает при первом запуске проекта.

Теперь проблема в том, что если вы отлаживаете второй раз, миграция не запустится. Это связано с тем, что таблица __MigrationHistory была обновлена, чтобы показать, что вы перешли на последнюю версию. Чтобы повторно протестировать миграцию, откройте консоль диспетчера пакетов и вернитесь к предыдущей миграции:

Update-Database –TargetMigration: ThePreviousMigrationName
робазавр
источник
8

Мой ответ может быть немного глупым, но, тем не менее, вот оно. Если у вас, как и у меня, иногда возникают проблемы с методом Seed (), я обычно просто создаю общедоступный метод, который вызывает Protect Seed ().

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

затем в моем HomeController я вызываю этот метод в режиме отладки.

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

Я знаю, что это немного неубедительное решение, но оно простое и быстрое. Конечно, это нужно делать после создания модели. Итак, пошагово:

  1. прокомментируйте метод seed и выполните update-database для создания модели
  2. раскомментируйте метод Seed () и вставьте «хак», о котором я упоминал выше.

  3. в конфигурации отключите автоматические миграции

    AutomaticMigrationsEnabled = false; // если у вас это отключено, пропустите этот шаг

  4. Отладьте свое приложение, исправьте ошибку и удалите «хак»

Руи Лима
источник
6

Вот более надежный метод, который поможет без особых хлопот:

Шаг № 1. Поместите этот фрагмент кода прямо над миграцией, которую вы хотите отладить:

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

Шаг № 2: Скомпилируйте проект, содержащий ваши миграции

Шаг № 3: Откройте консоль внутри выходного каталога (/ bin / Debug, / bin / Release и т. Д.), Содержащего dll ваших миграций.

Шаг №4: вызовите migrate.exe с параметром / scriptFile, чтобы запустить отладчик и выполнить отладку желаемой миграции базы данных.

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

Когда появится диалоговое окно отладчика-селектора, выберите экземпляр Visual Studio, который вы уже открыли.

XDS
источник
4

Вы можете добавить операторы Console.WriteLine в код миграции (не лучшее решение)

Обратите внимание: сообщения отображаются только в том случае, если вы запускаете код миграции с помощью migrate.exeутилиты (in pacakges\EntityFramework.x.y.z\tools). Они не будут отображаться, если вы запустите миграцию через консоль диспетчера пакетов.

Том Фергюсон
источник
Спасибо, Том ... Это был самый точный ответ, который я мог получить. Если никто не ответит на этот вопрос с лучшим решением, я отмечу его как ответ. :)
Daniel
Или бросьте Exception с вашим сообщением, которое вы хотите вернуть.
David d C e Freitas
2

Мне очень повезло с использованием «Debugger.Launch ()» (как в ответе m_david выше ) в другом месте, но внутри CreateDbContext кажется, что он каким-то образом и прикрепляется, и не прикрепляется. Я имею в виду, что он прикрепляется и начинает пытаться войти в файлы .asm и .cpp (внутренний код). Если я пытаюсь установить точку останова на Console.Writeline, которую я ЗНАЮ, запускается впоследствии (я могу видеть вывод ЛЮБОЙ «КОМАНДЫ миграции dotnet ef»), она одновременно выполняет ее и никогда не достигает точки останова.

Вместо этого у меня сработало следующее:

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

// Breakpoint after this...

Вы можете выполнить миграцию и вручную прикрепить с помощью Visual Studio и это будет на самом деле позволит вам пройти через код , как вы ожидаете, это просто больше боли. Что мне действительно стоит попробовать, так это комбинацию обоих методов ...

Брент Риттенхаус
источник
К какому процессу вы привязаны?
XDS
0

Я также нашел ловкий трюк здесь , чтобы получить подробную информацию об ошибке ...

По сути, трюк состоит в том, чтобы получить всю информацию из исключения, поместить ее в строку и выбросить новое исключение DbEntityValidationException с сгенерированной строкой и исходным исключением.

гигад
источник