14

これは私の最初の EF プロジェクトですので、ご容赦ください。

Department などのエンティティを更新するときは、コンテキストから取得し、その値を更新して、context.SaveChanges を呼び出します。ただし、Department.Employees を更新すると、EF はそれをおかしいとは思いません。

検索して、接続文字列で Multipleactiveresultsets=true を設定するオプションを思いつきましたが、次のことを知りたいです。

  • これは推奨される方法ですか?
  • これはパフォーマンスに悪影響を及ぼしますか / 何に注意する必要がありますか?
4

1 に答える 1

34

MARS を有効にする必要があるのは、同じ接続で複数のクエリを並行して実行する場合のみです。これは、次のようなことをすると発生します。

/* Foreach uses an iterator over the resultset of your query, but the query is not fetched
   immediately, instead the iterator internally triggers fetching for single
   processed record from opened data reader. Because of that the query and the reader
   are active until the iteration is over. */
foreach (var department in context.Departments.Where(...))
{
    /* The first query is still active on the connection but now you are executing
       lazy loading of all related employees =>. You are executing a second query and,
       without MARS, you will get an exception. */
    var employee = department.Employees.FirstOrDefault(...);
}

それを避ける方法は?

  • 遅延読み込みの代わりに熱心な読み込みを使用します。context.Departments.Include(d => d.Employees)
  • 遅延読み込みを使用する前に、部門全体の結果セットをマテリアライズします。これは、ループ内の従業員にアクセスしないことを意味します。
  • MARS を有効にすると、前述の例が機能します。

これは推奨される方法ですか?これはパフォーマンスに悪影響を及ぼしますか / 何に注意する必要がありますか?

解決しようとしている問題によって異なります。処理する部門が複数ある場合、従業員コレクションにアクセスすると、部門ごとに個別のクエリがトリガーされます。これは N+1 問題と呼ばれます。N 部門とそれらを取得する 1 つのクエリがあり、各部門に対して 1 つの追加クエリを実行する => N+1 クエリ。膨大な数の部門にとって、これはパフォーマンス キラーになります。

熱心な読み込みも防弾ソリューションではありません。パフォーマンスにも影響する可能性があります。場合によっては、必要なすべての部門を取得するために個別のクエリを実行し、必要なすべての従業員を取得するために個別のクエリを実行する必要があります。遅延読み込みをオフにしている場合は、関係が修正され、Employees プロパティが正しく埋められるはずです。ところで、私はData UserVoiceでこの機能をすぐにサポートできるよう提案しました。

于 2012-05-07T09:05:41.220 に答える