14

これは私の最初のEFプロジェクトです。Entity Framework 4.1のマルチアクティブな応答コード最初のコード

Departmentなどのエンティティを更新する場合は、コンテキストからコンテキストを取得し、値を更新してcontext.SaveChangesを呼び出します。しかし、Department.Employeesを更新すると、EFはその面白いものを見つけられません。

私が検索し、接続文字列に真Multipleactiveresultsets =を設定するオプションを思い付いたが、かどうかを知りたい:

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

答えて

33

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個のクエリを実行します。膨大な数の部署では、これがパフォーマンスの犠牲者になるでしょう。

熱心な読み込みは、弾丸ではありません。それはaffect performance as wellすることができます。場合によっては、必要なすべての部署を取得するために別々のクエリを実行し、必要なすべての従業員を取得するためにクエリを個別に実行するだけの場合もあります。遅延ロードを無効にしている場合は、関係を修正し、Employeesプロパティを正しく埋めなければなりません。 Btw、私はsuggestion on Data UserVoiceをこの機能をサポートするようにしました。

+0

ありがとうございます。私はあなたがこの投稿に気づくことを望んでいました。 Data UserVoiceでの提案にも投票してください。 –

+0

将来の参照のために、**は並列ではコードレベル**でしかないことも知っています。 * MARSは、単一の接続内で複数の要求のインターリーブされた実行を可能にします。つまり、バッチを実行できるようにし、実行中に他の要求を実行できるようにします。ただし、MARSはインタリーブの観点から定義されており、パラレル実行ではありません。* https://msdn.microsoft.com/en-us/library/ms131686.aspx – PedroC88

関連する問題