2011-07-07 7 views
20

私は次の機能を提供EF 4.1から単一のコールバックを取得するために書くことができ、最小限のコードは何ですか:どのようにしてEntity Frameworkを正しくプロファイルできますか?

私たちがあると思われる厄介なハックを使用する瞬間
  • OnSQLExecuted(DbCommand cmd, DateTime start, double durationMS, string stacktrace)

私はこのコールバックをアプリに最小限の影響で達成する方法について興味があります。


我々はhacking aroundによってMini Profilerにこれを配線することができます - intially我々は、しかし、デフォルトの工場でいじくるDatabase.DefaultConnectionFactoryを変更するには、あなたが同時に起こって2つのプロファイリングの工場を持っていないことを意味します。そこで、より積極的なルートを進めました。


一般的に使用される技術はかなり簡単です、あなたが実装:DbProviderFactoryIDbConnectionFactoryDbProviderServicesDbConnectionDbCommandDbDataReaderを、彼らはコールとプロファイルを横取りするような方法で。

これまでのところ、簡単に...あなたはこれを配線しようとすると、しかし、それは散らかっ取得します。

FileLoadException: The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047):それはEFの最新バージョンにいくつかの反射ハックと完全に爆弾を必要と

try 
    { 
     // ensure all the factories are loaded 
     DbProviderFactories.GetFactory("..."); 
    } 
    catch (ArgumentException) 
    { 
    } 

    Type type = typeof(DbProviderFactories); 

    DataTable table; 
    // SUPER UGLY - Can this be done in another way? 
    object setOrTable = (type.GetField("_configTable", BindingFlags.NonPublic | BindingFlags.Static) ?? 
        type.GetField("_providerTable", BindingFlags.NonPublic | BindingFlags.Static)).GetValue(null); 
    if (setOrTable is DataSet) 
    { 
     table = ((DataSet)setOrTable).Tables["DbProviderFactories"]; 
    } 

    table = (DataTable)setOrTable; 

    foreach (DataRow row in table.Rows.Cast<DataRow>().ToList()) 
    { 
     DbProviderFactory factory; 
     try 
     { 
      factory = DbProviderFactories.GetFactory(row); 
     } 
     catch (Exception) 
     { 
      continue; 
     } 

     var profType = typeof(MvcMiniProfiler.Data.EFProfiledDbProviderFactory<>).MakeGenericType(factory.GetType()); 


     DataRow profiled = table.NewRow(); 
     profiled["Name"] = row["Name"]; 
     profiled["Description"] = row["Description"]; 
     profiled["InvariantName"] = row["InvariantName"]; 
     profiled["AssemblyQualifiedName"] = profType.AssemblyQualifiedName; 
     table.Rows.Remove(row); 
     table.Rows.Add(profiled); 

    } 

これはFransAyendeの両方で報告されています。

プロファイル作成のファクトリとファミリを堅牢で洗練された方法で配線するにはどうすればよいですか?
コールバックを取得する他の方法はありますか?

答えて

9

最も簡単な方法はEntity Framework tracing wrappersを使用してEFTracingConnectionCommandFinishedに接続することです。開始時間は与えませんが、継続時間は(Nowから減算されていれば十分です。)

既存のコンテキストクラスへの参照を変更する必要があるため、「中程度」のコードに影響を与えると思います。しかし、それはかなり簡単です。

トレースを行い、実際のコールバックは必要ない場合、NuGetパッケージのサイズはsimple default tracing systemです。

編集(スタックトレースが追加されました): EFトレースラッパーはスタックトレースを提供しません。ソースを入手してそれをあまり難しくすることなく追加することができますが、それがパフォーマンスに影響すると思います。

+0

質問はEFv4.1に言及しています。トレースラッパーがDbContext APIで動作するかどうかはわかりません。私は長い間それを試してみたいが、私はまだそれをチェックしていない。 –

7

市販品ですが、EF Profをご覧になることを強くおすすめします。このツールは、他の製品の中でNH Prof、Uber Prof(NH + EF Prof)とRavenDBを作ったAyende(Oren Einiスペル?)によって開発されました。

は彼のNH教授、NHをチューニングするとき、それは非常に貴重だったと私はEF教授が、それぞれ同じように価値がある期待を購入しました。

+1

私たちはすでにオープンソースのセミワーキングソリューションを提供しています。http://code.google.com/p/mvc-mini-profiler/source/browse/MvcMiniProfiler/Data/ProfiledDbConnection.cs問題は、perfが漏れて再生されることですまずEFコードを入力します。私はAyendeが同じ問題を抱えていることは確かです。スティーブンスの答えについての完全な文脈についての私のコメントを見てください。 –

+0

@Sam Saffron私はあなたの答えを見ましたが、私はEF教授に関係するものは実際には見えません。それは非常によく似た問題を抱えているかもしれませんが、EF教授を試してみるべきでしょうか?またはAyendeと直接話せますか?彼は自分のブログやGoogleグループを通じてユーザーの質問に確実に答えます。 –

+0

上記のEFProfの推奨は2 -1票、EFProfの推奨は7 +1票です。私は狂った薬を飲んでいるように感じる! –

0

最初に:EFで直接自分のイベントをトリガーできるカスタム実装を探している場合は、それを忘れてしまいます。 ADO.NETチームは拡張ポイントを実装することをどうにかして忘れてしまいました。(ObjectQuery/DbQueryをSQLに変換するのではなく、遅延読み込みやデータの変更を処理しません。

私はEFで使用するすべてのトレースの実装は非常に明確に言及したトレースラッパーに記述されているなど、実際の工場をラップし、実際のConnectionCommandラップカスタムDbProviderFactoryを作成することによって行われていると信じています。

そこは、すでにあなたが

  • やりたい商用ツールにEF教授を記載されている素晴らしいツールですが、それは座席につき$ 300かかります。
  • 代替品はHuagati Query Profilerです。特にthis screen shotはあなたが探しているもののようです。価格はずっと低く(座席あたり40ドル)、Linq-to-SQL、Entity Framework、LLBLGenをサポートしています。

どちらのツールも無料で試用できるため、ダウンロードして試すことができます。

Btw。おそらく、VS 2010 Ultimateをお持ちの場合、Intelli Traceから探している多くの情報を得ることができます。現在利用可能なすべての選択肢についてはMSDN Magazineで読むことができます。

DbContextまたはObjectContext(EFv4.1について言及しています)を使用していますか? DbContext APIでどのように動作するのかよくわからないので、言及されたツールとトレースラッパーがObjectContext API用に作成されました。 DbContextからObjectContextを取得することはできますが、ツールで一般的な接続ではなくEntityConnectionが必要な場合は問題になります。

+0

これはdbcontextで動作するようにしたいと思います...この作業はmvcミニプロファイラーのためのものです。スティーブンスの答えに対するコメントを参照してください... –

+0

EF 6では今やインターセプトポイントがあり、タイマーとロガーを追加できます。 IDbCommandInterceptorを見てください。私は 'long-running'クエリを検出し、ログからピックアップできるように警告付き完全SQLをログに記録します。 –

0

Entity Framework Profilerをお勧めします。月額サブスクリプションは、毎月最低16,000米ドル必要です。 DbContextにいくつかのパフォーマンス上の問題があり、それらを修正するための優れた視覚的情報が提供されていました。 EFプロファイラを継続的な統合サーバーと統合し、パフォーマンスを向上させることができます。

http://efprof.com/

+0

私はプロファイラーを探していません、私はプロファイラーが使用できる技術を探しています。 –

関連する問題