Miniprofiler在缺少CreatedOn列时中断

Quo*_*ter 11 c# entity-framework mvc-mini-profiler

我在我的Web应用程序(asp.net-mvc)中为EF 6.1 安装了miniprofiler ,它在一行中断,出现以下错误消息:

MiniProfiler.dll中出现"System.Data.SqlClient.SqlException"类型的异常,但未在用户代码中处理

附加信息:无效的列名称'CreatedOn'.

为什么会这样?我过去使用EF 5并升级到版本6,后来升级到6.1.

这个这篇文章有一些解决方法,并且还说当你从4.3版本升级时会发生这种情况.在我的网络应用程序中并非如此.

有没有人通过不解决这个问题来修复这个错误?

Oli*_*veu 11

我认为调试器会中断,因为PDB文件包含在MiniProfiler NuGet包中.

当实体框架尝试确定列是否CreatedOn存在于__MigrationHistory表中时,实例框架抛出异常时发生中断.(使用IlSpy提取的代码System.Data.Entity.Migrations.History.HistoryRepository.GetUpgradeOperations())

bool flag = false;
try
{
    this.InjectInterceptionContext(legacyHistoryContext);
    using (new TransactionScope(TransactionScopeOption.Suppress))
    {
        (
            from h in legacyHistoryContext.History
            select h.CreatedOn).FirstOrDefault<DateTime>(); // Will throw an exception if the column is absent
    }
    flag = true;
}
catch (EntityException)
{
}
if (flag)
{
    // Remove the column if present (if no exception was thrown)
    yield return new DropColumnOperation("dbo.__MigrationHistory", "CreatedOn", null);
}
Run Code Online (Sandbox Code Playgroud)

您可以注意到,如果手动创建列以避免异常,则会在下次运行时将其删除,异常将返回.由于MiniProfiler将自己置于DbCommand.ExecuteReader()中,因此它位于catch之前的异常路径上(linq查询转换为sql查询,最后使用DbCommand执行).

你有两个解决方案来防止发生中断:

禁用该类型的异常中断

您可以在Visual Studio调试器中禁用中断特定异常.我正在使用Sql CE,所以我首先声明了SqlCeException(步骤2到4).如果您正在使用SqlServer,则可以跳过此步骤,只需检查引发的异常类型是否已在列表中.

  1. 打开'Exceptions'对话框(菜单Debug/Exceptions)
  2. '添加...'按钮,选择'公共语言运行时例外'作为类型.
  3. 将异常名称设置为'System.Data.SqlServerCe.SqlCeException'
  4. 验证并保持"异常"对话框打开.
  5. 打开列表中的"公共语言运行时异常"部分.
  6. 取消选中前面的两个复选框System.Data.SqlServerCe.SqlCeException(或您的案例中抛出的异常)并关闭对话框.

这个例外不应该导致从现在开始.但是,调试器在您自己的代码中不会中断,如果MiniProfiler在另一种情况下抛出另一种类型的异常,则会再次发生中断.

删除PDB文件

您可以删除MiniProfiler PDB的文件,但您必须删除NuGet引用:

  1. 找到并制作MiniProfiler dll的副本(来自项目的bin文件夹).当然,不要复制pdb文件.
  2. 删除所有对MiniProfiler的NuGet引用.
  3. 添加对已复制到其他文件夹的dll的引用.

缺点是您将无法使用NuGet更新MiniProfiler.

也许更好的解决方案是从NuGet包中删除PDB,但我不知道是否需要它们用于其他目的.

编辑

正如jrummell在他的评论中指出的那样,可以使用Post Build Event删除PDB的文件.这样你就可以保留你的NuGet引用.

  • 我添加了一个Post Build Event以删除PDB,它似乎运行良好:`del"$(TargetDir)MiniProfiler.pdb"/ q/s` (10认同)