Miniprofiler在缺少CreatedOn列时中断

时间:2014-05-10 23:16:33

标签: c# entity-framework mvc-mini-profiler

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

  

发生了'System.Data.SqlClient.SqlException'类型的异常   MiniProfiler.dll但未在用户代码中处理

     

其他信息:无效的列名称'CreatedOn'。

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

Thisthis帖子有一些解决方法,并且还说当您从4.3版升级时会发生这种情况。在我的网络应用程序中并非如此。

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

1 个答案:

答案 0 :(得分:11)

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

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

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);
}

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

您有两种解决方案可以防止发生中断:

禁用此类异常的中断

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

  1. 打开“例外”对话框(菜单“调试/例外”)
  2. '添加...'按钮,选择'公共语言运行时例外'作为类型。
  3. 将异常名称设置为“System.Data.SqlServerCe.SqlCeException”
  4. 验证并打开“例外”对话框。
  5. 打开列表中的“公共语言运行时例外”部分。
  6. 取消选中System.Data.SqlServerCe.SqlCeException前面的两个复选框(或您的案例中引发的异常)并关闭对话框。
  7. 该异常不应该导致从现在开始。 但是,调试器在您自己的代码中不会中断,如果MiniProfiler在另一种情况下抛出另一种类型的异常,则会再次发生中断。

    删除PDB文件

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

    1. 找到并制作MiniProfiler dll的副本(来自项目的bin文件夹)。当然,不要复制pdb文件。
    2. 删除对MiniProfiler的所有NuGet引用。
    3. 添加对已复制到其他文件夹的dll的引用。
    4. 缺点是您将无法使用NuGet更新MiniProfiler。

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

      修改

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