It may be related, but another problem, but since it was Anders' message that led me to a solution, I thought that I also post this solution.
Problem:
If the MiniProfiler is initialized before the Entity Framework database initialization strategies are executed, the initialization will fail with a missing migration table.
If the initialization strategies of the Entity Framework database are executed, access to the objects fails with the exception of a type exception, because MiniProfiler DbConnection tries to force the SqlConnection into the variable (in the internal generic format).
Cause:
When the MiniProfiler is initialized, it uses reflection to retrieve the collection of database providers from the private static field in System.Data.Common.DbProviderFactories. He then rewrites this list using the MiniProfiler firmware providers to replace local providers. This allows MiniProfiler to easily intercept any calls to the database.
When the Entity Framework initializes, it starts compiling data models and creating cached initialized databases stored in System.Data.Entity.Internal.LazyInternalContext inside some private static fields. After they are created, queries to DbContext use cached models and databases that are internally typed to use the providers that existed during initialization.
When the Entity Framework database initialization strategy is launched, it needs access to its first Sql provider, not MiniProfiler, to properly create SQL to create tables. But once these calls for the native provider are made, the native provider is cached in the LazyInternalContext, and we can no longer enter MiniProfiler pads without crashing at runtime.
My decision:
Access private collections inside System.Data.Entity.Internal.LazyInternalContext and flush cached compiled models and initialized databases.
If I perform this cleanup between the actions of the EF database initialization strategies and the MiniProfiler initialization, then it will be possible to insert MiniProfiler gaskets without a subsequent malfunction.
Code: This code helped:
Type type = typeof(DbContext).Assembly.GetType("System.Data.Entity.Internal.LazyInternalContext"); object concurrentDictionary = (type.GetField("InitializedDatabases", BindingFlags.NonPublic | BindingFlags.Static)).GetValue(null); var initializedDatabaseCache = (IDictionary)concurrentDictionary; if (initializedDatabaseCache != null) initializedDatabaseCache.Clear(); object concurrentDictionary2 = (type.GetField("CachedModels", BindingFlags.NonPublic | BindingFlags.Static)).GetValue(null); var modelsCache = (IDictionary)concurrentDictionary2; if (modelsCache != null) modelsCache.Clear();
Attention:
It looks like the internal field names in LazyInternalContext change between versions of EF, so you might need to change this code to work with the exact version of EF that you included in your project.