我在使用 ASP.Net MVC 3 和实体框架代码优先构建的项目中使用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
是类型ProfiledDbConnection
(即使当前的 MiniProfiler 为空)。
在实例化之前,该方法MiniProfiler.Start()
在 Global 方法中被调用。我也为每个请求调用 Start 方法,但如果用户不是正确的角色,则调用 stop :Application_BeginRequest()
DbContext
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 Code First 分析生成的 sql。
实体框架期待与类型的连接,SqlConnection
这当然不是。
这是我的连接字符串的示例(请注意 providerName)
<add name="MyDbContext" connectionString="Server=.\SQLEXPRESS; Database=MyDatabase;Trusted_Connection=true;MultipleActiveResultSets=true" providerName="System.Data.SqlClient" />
我试图创建我自己的ProfiledDbConnection
继承版本,SqlConnection
但它是一个密封类。
如果有某种方式可以告诉实体框架有关自定义连接类型的信息,那么这可能会起作用。我尝试将providerName
连接字符串中的设置为,MvcMiniProfiler.Data.ProfiledDbConnection
但没有奏效。
所以。问题的演变可能是:如何将自定义连接类型传递给 Entity Framework Code First?