11

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?

Community
  • 1
  • 1
Quoter
  • 4,236
  • 13
  • 47
  • 69
  • http://community.miniprofiler.com/t/sqlexception-on-ef-5-w-net-4-5/71/2 – Oleksii Aza May 10 '14 at 23:54
  • I am aware of that work around/link. However, the question was how to fix it by not working around it (means no workaround). – Quoter May 11 '14 at 10:16
  • Is there more information you can provide about the exception? Maybe some source code as well? – Evandro Pomatti May 12 '14 at 00:35
  • You could reproduce this with any project using EF 6 in combination with miniprofiler EF 6. And do a database call in the `Index()` `ActionResult` in the `HomeController` (example `dbContext.Users`). Make sure you have configured miniprofiler (example `MiniProfilerEF6.Initialize()` in global.asax.cs. – Quoter May 12 '14 at 10:11
  • @Quoter this error does not occur in the Sample.Mvc project in the MiniProfiler repo. So it is more than just using EF6 and MP.EF6. I have used MP.EF6 in both code first (see Sample.Mvc) and Db first scenarios and have not yet seen this error. Any more info that you can provide for causing this to occur would be helpful. – Yaakov Ellis May 14 '14 at 08:10

1 Answers1

11

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.

Olivier Leneveu
  • 518
  • 7
  • 10
  • I'm using `MSSQL` as the database storage. If you uncheck that box, doesn't that stop all other `SqlCeException` exceptions happening from being thrown? – Quoter May 14 '14 at 18:19
  • I suppose that you mean that you are using Sql Server. In that case you should uncheck `System.Data.SqlClient.SqlException` (under `System.Data.SqlClient`). This will not prevent the exceptions from being throw, this will just instruct the debugger not to break when they are thrown. – Olivier Leneveu May 15 '14 at 09:12
  • 10
    I added a Post Build Event to remove the PDB and it seems to work well: `del "$(TargetDir)MiniProfiler.pdb" /q /s` – jrummell Sep 15 '14 at 17:54