Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Miniprofiler breaks on missing CreatedOn column

I have miniprofiler installed in my web app (asp.net-mvc) for EF 6.1, and it breaks on a line with the following error message:

An exception of type 'System.Data.SqlClient.SqlException' occurred in MiniProfiler.dll but was not handled in user code

Additional information: Invalid column name 'CreatedOn'.

Why is this happening? I had EF 5 in the past and upgraded to version 6 and later on 6.1.

This and this post have some workarounds, and are also saying that this happens when you upgraded from version 4.3. That's not the case in my web app.

Does anyone actually fixed this bug by not working around it?

like image 659
Quoter Avatar asked May 10 '14 23:05

Quoter


1 Answers

I think that the debugger breaks because the PDB files are included in the MiniProfiler NuGet packages.

The break occurs when an exception is thrown by the entity framework as it tries to determine if the column CreatedOn exists in the __MigrationHistory table. (Code extracted using IlSpy from 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);
}

You can notice that if you manually create the column to avoid the exception, it will be removed on the next run and the exception will come back. As MiniProfiler interpose itself in DbCommand.ExecuteReader(), it is on the path of the exception before the catch (the linq query translates to a sql query, and is finally executed using a DbCommand).

You have two solution to prevent the break from occuring:

Disable breaks for that type of exception

You can disable breaking on a particular exception in the Visual Studio debugger. I'm working with Sql CE so I had first to declare the SqlCeException (step 2 to 4). If you are working with SqlServer you can probably skip this step, just check that the type of the exception that is thrown is already in the list.

  1. Open the 'Exceptions' dialog (menu Debug/Exceptions)
  2. 'Add...' button, select 'Common Language Runtime Exceptions' as type.
  3. Set the exception name to 'System.Data.SqlServerCe.SqlCeException'
  4. Validate and keep the 'Exceptions' dialog opened.
  5. Open the 'Common Language Runtime Exceptions' section in the list.
  6. Uncheck both check boxes in front of System.Data.SqlServerCe.SqlCeException (or the exception that is thrown in your case) and close the dialog.

The exception should not cause a break from now. However, the debugger will not break even in your own code, and if another type of exception is thrown by MiniProfiler in another case a break will occur again.

Remove the PDB files

You can remove the MiniProfiler PDB's files, but you will have to remove the NuGet references:

  1. Locate and make a copy of the MiniProfiler dll's (from your project's bin folder). Of course, do not make a copy of the pdb files.
  2. Remove all NuGet references to MiniProfiler.
  3. Add references to the dll's you have copied to a different folder.

The drawback is that you will not be able to use NuGet to update MiniProfiler.

Maybe a better solution would be to remove the PDB from the NuGet package, but I don't know if they are needed for another purpose.

Edit

As jrummell points it out in his comment, the PDB's files can be removed using a Post Build Event. That way you can keep your NuGet references.

like image 97
Olivier Leneveu Avatar answered Nov 07 '22 18:11

Olivier Leneveu