1

Entity Framework と IEnumerables を使用することの優れた機能の 1 つは、DB からデータが実際に照会されるタイミングを気にする必要がないことです。クエリ結果となるものを渡すだけで、実際に必要になったときに EF が取得します。ただし、SELECT コードの周りに try/catch を配置するとなると、DB がいつ照会されるかを正確に把握するのは容易ではないため、問題になります。

現在、断続的な DB タイムアウトが発生しています。発生したときに EF が使用する SQL をログに記録したいのですが、上記で説明した問題が発生しています。これを処理する便利な方法はありますか?それとも私は問題を間違って見ていますか?

4

3 に答える 3

4

除外されると予想されるコードの機能ブロックを実行するときは常に、適切な try/catch エラー処理を使用する必要があります (この場合は、EF データ コンテキストに対してラムバ式や LINQ クエリを実行するときなど)。本当の問題は、なぜタイムアウトを受け取るのかということです。

タイムアウトの診断と修正に役立つ可能性のある、上記のステートメントの潜在的な誤りを1つ指摘したいと思います。「...データが実際にデータベースからいつ照会されるかについて心配する必要はありません。」名目上の複雑な LINQ クエリを作成する過程で、実際には、データベースがいつヒットするかを十分に認識しておく必要があることをお勧めします。ToList()、Distinct()、Count() などの呼び出しを介して実体化する前に、LINQ クエリをできるだけ長く IQueryable として保持する必要があります。

したがって、百万行のテーブルをクエリしていて、潜在的な基準を解析しているとしましょう。ToList() を使用してクエリを具体化するのは最後まで待つ必要があります。これは、EF によって生成された SQL ステートメントが実行されるポイントであるためです。データベースで実行されます:

using(var context = CreateEFContextFactory())
{
   var x = (from d in context.MyBigTable select d);
   if(!string.IsNullOrWhitespace(stringParam1))
      x = (from d in x where x.Field1 == stringParam1 select d);
   if(intParam2 > 0)
      x = (from d in x where x.Field2 == intParam2 select d);

   var listOfMyBigTableObjects = x.Distinct().ToList();  //point of sql execution
}
于 2012-10-05T20:41:54.563 に答える
1

ここでいくつかのことをしようとしているように思えます: Entity Framework によって生成されている SQL を表示し、グローバル エラー ハンドラーを追加します。

.NET Web アプリまたは API を作成している場合は、elmahなどの既定のエラー ハンドラーを追加できます。MVC を使用している場合、グローバル エラー ハンドラーの答えはelmah をグローバル ハンドラーとして設定する方法を示していますが、その例を簡単にカスタマイズして、独自のログ ユーティリティを使用することができます。

于 2012-10-05T21:31:57.227 に答える
1

.ToList().FirstOrDefault()、など、クエリがいつ実行されるかはある程度わかっています.Any()。したがって、try catchそれらの周りにブロックを配置する必要があります。

于 2012-10-05T20:22:41.383 に答える