Entity Framework Code First で mvc-mini-profiler データベース プロファイリングを使用する 質問する

Entity Framework Code First で mvc-mini-profiler データベース プロファイリングを使用する 質問する

私は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 をプロファイルするために、接続を渡そうとしています。

プロファイルされた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問題が解決する場合がありますが、よりスマートなプロバイダーの中には、これを透過的に処理できるものもあります。

おすすめ記事