私はmvc-ミニプロファイラー私のプロジェクトは、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 が null の場合でも)。
メソッドは、インスタンス化される前に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();
}
これが何かに影響するかどうかはわかりませんが、DbContext
次の初期化子を使用して、StructureMap を IoC としても使用しています。
For<MyDbContext>().Singleton().HybridHttpOrThreadLocalScoped();
ここに同様の質問があり、そのユーザーに何が起こっているのかがわかりやすく説明されていることは理解していますが、私の問題は解決されていないようです。
編集:
ProfiledDbConnection
明確にするために、Entity Framework Code First から生成された SQL をプロファイルするために、接続を渡そうとしています。
Entity Framework は、SqlConnection
当然ながらこの型ではない接続を期待しています。
以下は私の接続文字列の例です(providerNameに注意してください)
<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 に渡すにはどうすればよいですか?
ベストアンサー1
これは現在完全にサポートされています。最新のソースを確認するか、nuget からパッケージを取得してください。
nuget を使用する場合は、MiniProfiler.EF パッケージが必要になります。(1.9.1 以上)
これをサポートするには、EF コードファースト プロキシとしての動作をサポートするために、基盤となるプロキシ オブジェクトに大量の変更を加える必要がありました。
このサポートを追加するには:
ランニング中Application_Start
:
MiniProfilerEF.Initialize();
注記: EF Code First は、テーブル メタデータを というテーブルに格納します。EdmMetadata
このメタデータは、プロバイダーをエンティティ キーの一部として使用します。プロバイダーを非プロファイル プロバイダーとして初期化した場合は、このメタデータを再構築する必要があります。 のすべての行を削除するとEdmMetadata
問題が解決する場合がありますが、よりスマートなプロバイダーの中には、これを透過的に処理できるものもあります。