调试代码优先的Entity Framework迁移代码


138

我首先在网站上使用Entity Framework代码,而我只是想知道是否有任何方法可以调试迁移代码。您知道像设置断点之类的东西。

我正在使用Package Manager Console使用来更新数据库Update-Database

谢谢


这只是标准的C#代码-是的,当然,您可以在其中设置断点.....
marc_s 2013年

1
但由于我使用的是Package Manager控制台,因此该应用程序实际上并未运行。
丹尼尔(Daniel)

1
然后,不要从Package Manager控制台升级,而是将迁移初始化程序设置为默认初始化程序,以便在您的应用程序第一次连接数据库时就迁移数据库。
Wiktor Zychla

我正在使用迁移代码更新数据库,而无法停止应用程序并再次运行它以运行初始化程序。
丹尼尔(Daniel)

我不使用SQL的原因是用于更新的代码相当复杂,并且几乎不可能使用SQL来实现。
丹尼尔(Daniel)

Answers:


255

我知道EF Code First Migrations是相对较新的工具,但是请不要忘记您仍然在.NET中。

因此,您可以使用:

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

之后,您可以看到InnerException。

或者,您可以使用try ... catch语句,如下所示: 异常处理Entity Framework


3
是的,这在通过程序包管理器控制台运行更新数据库时有效。非常便利!
汤姆·弗格森

11
我将此添加到Configuration.Seed方法的顶部。它会导致弹出窗口,使您可以选择Visual Studio来调试代码。但是,当我选择它时,系统会挂起(也许不相关)。
Talon 2013年

3
这段代码放在哪里?如果有人可以帮忙!谢谢。
Aritra B 2014年

4
在您的配置类的构造函数中。
Casey 2014年

5
@Talon Go喝杯咖啡,等到您回来时,可能弹出了另一个Visual Studio实例。:)
Corstian Boerman 2014年

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中,我在Debug模式下调用此方法。

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

我知道这是一个有点la脚的解决方案,但是它简单快捷。当然,这必须在创建模型之后完成。所以一步一步来:

  1. 注释种子方法并执行更新数据库以创建模型
  2. 取消注释方法Seed()并插入上面提到的“ hack”。

  3. 在配置中禁用自动迁移

    AutomaticMigrationsEnabled = false; //如果您已禁用此功能,则已跳过此步骤

  4. 调试您的应用程序,修复错误并删除“ hack”


5

这是一种更加防故障的方法,可以轻松完成操作:

步骤#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:使用/ scriptFile参数调用migration.exe以启动调试器并实际调试所需的db-migration

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

弹出调试器选择器对话框后,选择您已经打开的Visual Studio实例。


4

您可以将Console.WriteLine语句添加到迁移代码中(不是一个很好的解决方案)

请注意,只有使用migrate.exe实用程序(在中pacakges\EntityFramework.x.y.z\tools)运行迁移代码时,才会显示消息。如果通过Package Manager控制台运行迁移,则不会显示它们。


谢谢汤姆...这是我能得到的最接近的答案。如果没有人提供更好的解决方案,我将其标记为答案。:)
Daniel

或在要返回的消息中引发异常。
David d C e Freitas

2

我在其他地方使用“ Debugger.Launch()”(例如,在上面的m_david的答案中)有很多运气,但是在CreateDbContext内部,它似乎以某种方式既附着又不附着。我的意思是,它附加并开始尝试进入.asm文件和.cpp文件(内部代码)。如果我尝试在Console.Writeline上设置一个断点,然后知道该断点将被执行(我可以看到任何“ dotnet ef migrations COMMAND”的输出),那么它既会执行该断点,也不会碰到断点。

这是对我有用的:

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

// Breakpoint after this...

您可以执行迁移和手动使用Visual Studio连接,它真正让你通过代码像你期望的那样,它只是一种痛苦。我真正应该尝试的是两种方法的结合...


您要附加到哪个流程?
XDS

-1

在这里还找到了一个巧妙的技巧来获取错误详细信息...

基本上,诀窍是从异常中获取所有信息,将其放入字符串中,并使用生成的字符串和原始异常抛出新的DbEntityValidationException。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.