首先使用实体​​框架代码使用mvc-mini-profiler数据库分析

我在使用ASP.Net MVC 3和entity framework代码优先的项目中使用mvc-mini-profiler 。

一切都很好,直到我试图通过在ProfiledDbConnection包装连接添加数据库分析,如文档中所述。 由于我正在使用DbContext,我试图提供连接的方式是通过使用静态工厂方法的构造函数:

 public class MyDbContext : DbContext { public MyDbContext() : base(GetProfilerConnection(), true) { } private static DbConnection GetProfilerConnection() { // Code below errors //return ProfiledDbConnection.Get(new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionName"].ConnectionString)); // Code below works fine... return new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionName"].ConnectionString); } //... } 

使用ProfiledDbConnection ,出现以下错误:

ProviderIncompatibleException: The provider did not return a ProviderManifestToken string.

堆栈跟踪:

 [ArgumentException: The connection is not of type 'System.Data.SqlClient.SqlConnection'.] System.Data.SqlClient.SqlProviderUtilities.GetRequiredSqlConnection(DbConnection connection) +10486148 System.Data.SqlClient.SqlProviderServices.GetDbProviderManifestToken(DbConnection connection) +77 System.Data.Common.DbProviderServices.GetProviderManifestToken(DbConnection connection) +44 [ProviderIncompatibleException: The provider did not return a ProviderManifestToken string.] System.Data.Common.DbProviderServices.GetProviderManifestToken(DbConnection connection) +11092901 System.Data.Common.DbProviderServices.GetProviderManifestToken(DbConnection connection) +11092745 System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection) +221 System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext) +61 System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input) +1203482 System.Data.Entity.Internal.LazyInternalContext.InitializeContext() +492 System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) +26 System.Data.Entity.Internal.Linq.InternalSet`1.Initialize() +89 System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext() +21 System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider() +44 System.Linq.Queryable.Where(IQueryable`1 source, Expression`1 predicate) +135 

我已经介入, ProfiledDbConnection.Get返回的types是ProfiledDbConnection.Gettypes(即使当前的MiniProfiler为null)。

在实例化DbContext之前,在Global Application_BeginRequest()方法中DbContext Application_BeginRequest()方法。 我也为每个请求调用Start方法,不pipe如何调用stop,如果用户不是正确的angular色:

  protected void Application_BeginRequest() { // We don't know who the user is at this stage so need to start for everyone MiniProfiler.Start(); } protected void Application_AuthorizeRequest(Object sender, EventArgs e) { // Now stop the profiler if the user is not a developer if (!AuthorisationHelper.IsDeveloper()) { MvcMiniProfiler.MiniProfiler.Stop(discardResults: true); } } protected void Application_EndRequest() { MiniProfiler.Stop(); } 

我不确定这是否会影响事件,但是我还使用以下初始化程序将StructureMap用作IoC作为DbContext

 For<MyDbContext>().Singleton().HybridHttpOrThreadLocalScoped(); 

我知道在这里有一个类似的问题,很好的解释了这个用户正在发生的事情,但是这似乎并没有解决我的问题。

编辑:

为了清楚。 我试图通过连接作为ProfiledDbConnection为了从entity framework代码优先生成生成的sql。

Profiled Sql

entity framework期望与SqlConnectiontypes的连接,当然这不是。

这是我的连接string的一个例子(注意providerName)

 <add name="MyDbContext" connectionString="Server=.\SQLEXPRESS; Database=MyDatabase;Trusted_Connection=true;MultipleActiveResultSets=true" providerName="System.Data.SqlClient" /> 

我试图创build我自己的从SqlConnectioninheritance的ProfiledDbConnection的版本,但它是一个密封的类。

如果有某种方式告诉entity framework关于自定义连接types,那么也许这将工作。 我尝试将连接string中的providerName设置为MvcMiniProfiler.Data.ProfiledDbConnection但没有奏效。

所以。 也许这个问题的演变将是:你如何将自定义连接types传递给entity framework代码优先?

现在完全支持,请查看最新的源代码或从nuget获取软件包。

如果您正在使用nuget,您将需要MiniProfiler.EF软件包。 (1.9.1及以上)

支持这项工作需要对底层代理对象进行大量的修改,以支持充当EF代码的第一代理。

要添加这个支持:

Application_Start运行期间:

MiniProfilerEF.Initialize();

注意 :EF Code First会将表元数据存储在名为EdmMetadata的表中。 这个元数据使用提供者作为实体键的一部分。 如果您将提供程序初始化为非简介提供程序,则必须重新构build此元数据。 从EdmMetadata删除所有的行可能会诀窍,或者一些聪明的提供者能够透明地处理。

我仍然有问题得到这个工作,发现我需要重命名或删除连接string来获取Database.DefaultConnectionFactory工作。

有关更多详细信息,请参阅此答案。

在我的经验中,这个错误一直是一个无效的连接string,或缺乏连接到数据库,如“连接中发生networking服务错误…”。

还要注意,DbContext只需要构造函数中的“connectionStringKey”就好

 public MyDbContext() : base("MyConnectionName", true) { }