Я использую mvc-mini-profiler в своем проекте, построенном с использованием ASP.Net MVC 3 и Entity Framework в первую очередь.
Все прекрасно работает, пока я не попытаюсь добавить профилирование базы данных, поместив соединение в 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 Application_BeginRequest()
до создания экземпляра DbContext
.Я также вызываю метод Start для каждого запроса независимо, но вызываю stop, если пользователь не в правильной роли:
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
, чтобы профилировать сгенерированный sql из Entity Framework Code First.
Entity Framework ожидает соединения с типом SqlConnection
, что, конечно, не так.
Вот пример моей строки подключения (обратите внимание, имя провайдера)
<add name="MyDbContext" connectionString="Server=.\SQLEXPRESS; Database=MyDatabase;Trusted_Connection=true;MultipleActiveResultSets=true" providerName="System.Data.SqlClient" />
Я попытался создать свою собственную версию ProfiledDbConnection
, унаследованную от SqlConnection
, но она запечатанаучебный класс.
Если есть какой-то способ сообщить Entity Framework о пользовательском типе соединения, возможно, это сработает.Я попытался установить providerName
в строке подключения на MvcMiniProfiler.Data.ProfiledDbConnection
, но это не сработало.
Итак.Возможно, эволюция вопроса будет такой: как вы можете передать пользовательский тип соединения в Entity Framework Code First?