调试代码优先的实体框架迁移代码
Posted
技术标签:
【中文标题】调试代码优先的实体框架迁移代码【英文标题】:Debug code-first Entity Framework migration codes 【发布时间】:2013-06-14 16:13:30 【问题描述】:我首先在我的网站中使用实体框架代码,我只是想知道是否有任何方法可以调试迁移代码。你知道,比如设置断点之类的东西。
我正在使用包管理器控制台使用 Update-Database
更新数据库。
谢谢
【问题讨论】:
这只是标准的 C# 代码 - 所以是的,当然,您可以在其中设置断点..... 但应用程序实际上并没有运行,因为我正在使用包管理器控制台。 然后不要从包管理控制台升级,而是将迁移初始化程序设置为默认初始化程序,以便在您的应用程序第一次连接到它时迁移数据库。 我正在使用迁移代码更新我的数据库,但我无法停止应用并再次运行它以运行初始化程序。 我不使用SQL的原因是更新的代码比较复杂,几乎不可能用SQL来实现。 【参考方案1】:我知道 EF Code First Migrations 是一个相对较新的工具,但别忘了你还在 .NET 中。
所以你可以使用:
if (System.Diagnostics.Debugger.IsAttached == false)
System.Diagnostics.Debugger.Launch();
之后你可以看到你的 InnerException。
或者你可以像这样使用 try...catch 语句: Exception handling Entity Framework
【讨论】:
是的,这在通过包管理器控制台运行更新数据库时有效。非常方便! 我将此添加到我的 Configuration.Seed 方法的顶部。它会导致一个弹出窗口,让您选择您的 Visual Studio 来调试代码。但是,当我选择它时,我的系统会挂起(可能不相关)。 这段代码放在哪里?如果有人可以帮忙!谢谢。 在你的配置类的构造函数中。 @Talon 去喝杯咖啡,等你回来的时候,可能会弹出另一个 Visual Studio 实例。 :)【参考方案2】:要在数据库迁移中遇到断点,请在初始化时将上下文设置为 MigrateDatabaseToLatestVersion。
Database.SetInitializer(new MigrateDatabaseToLatestVersion<EnterContextHere, Configuration>());
然后您只需正常调试(使用 f5 运行),断点将在您第一次运行项目时命中。
现在的问题是,如果您第二次调试,迁移将无法运行。这是因为 __MigrationHistory 表已更新,表明您已迁移到最新版本。要重新测试迁移,请打开包管理器控制台并降级到之前的迁移:
Update-Database –TargetMigration: ThePreviousMigrationName
【讨论】:
【参考方案3】:我的回答可能有点傻,但无论如何都可以。 如果您像我一样,有时在 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();
我知道这是一个有点蹩脚的解决方案,但它简单快捷。 当然,这必须在模型创建后完成。 所以一步一步来:
-
注释种子方法并执行更新数据库创建模型
取消注释方法 Seed() 并插入我上面提到的“hack”。
在配置中禁用自动迁移
AutomaticMigrationsEnabled = false;//如果你禁用了这个已经跳过这一步
调试您的应用程序,修复错误并移除“hack”
【讨论】:
【参考方案4】:这里有一个更防失败的方法,它可以轻松解决问题:
第 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:在包含迁移的 dll 的输出目录(/bin/Debug、/bin/Release 等)中打开一个控制台
步骤#4:使用 /scriptFile 参数调用 migrate.exe 以启动调试器并实际调试所需的 db-migration
migrate.exe "Your.Migrations.Assembly.dll" /scriptFile="foo.sql" /verbose /startupConfigurationFile="Your.Migrations.Assembly.config"
一旦弹出调试器选择器对话框,选择您已经打开的 Visual Studio 实例。
【讨论】:
【参考方案5】:您可以在迁移代码中添加 Console.WriteLine 语句(不是一个很好的解决方案)
请注意,仅当您使用migrate.exe
实用程序(在pacakges\EntityFramework.x.y.z\tools
中)运行迁移代码时才会显示这些消息。如果您通过包管理器控制台运行迁移,它们将不会显示。
【讨论】:
谢谢汤姆...这是我能得到的最接近的答案。如果没有人用更好的解决方案回答这个问题,我会将其标记为答案。 :) 或者在你想要返回的消息中抛出一个异常。【参考方案6】:我在其他地方使用“Debugger.Launch()”(如m_david's answer above)很幸运,但在 CreateDbContext 内部,它似乎以某种方式既附加又不附加。我的意思是,它附加并开始尝试进入 .asm 文件和 .cpp 文件(内部代码)。如果我尝试在 Console.Writeline 上设置断点,我知道之后会执行(我可以看到任何“dotnet ef migrations COMMAND”的输出)它都会执行它并且永远不会到达断点。
这对我有用:
while (!System.Diagnostics.Debugger.IsAttached)
System.Threading.Thread.Sleep(10);
// Breakpoint after this...
您可以使用 Visual Studio 执行迁移并手动附加,它将实际上让您可以像您期望的那样逐步执行代码,只是更痛苦。我真正应该尝试的是两种方法的结合......
【讨论】:
你附加到哪个进程?【参考方案7】:我还发现了一个巧妙的技巧here 来获取错误详细信息...
基本上,诀窍是从异常中获取所有信息,将其放入字符串中,然后使用生成的字符串和原始异常抛出一个新的 DbEntityValidationException。
【讨论】:
以上是关于调试代码优先的实体框架迁移代码的主要内容,如果未能解决你的问题,请参考以下文章