2012-04-11 18 views
1

私のドメインサービスのインクルードにwhere句を入れることができないようです - いくつかのループを使っていくつかのlookupGroupsに必要なデータを取得しています。遅延ロードのナビゲーションプロパティ

var _lookupGroups = _lookupGroupRepository.All(); 
     var _lookupValues = _institutionLookupValueRepository.All().Where(x => x.InstitutionID == _userProfile.InstitutionID); 

     int i = 0; 

     foreach (var _group in _lookupGroups) 
     { 
      var _values = _lookupValues.Where(x => x.LookupGroupID == _group.LookupGroupID); 

      foreach (var _value in _values) 
      { 
       _group.InstitutionLookupValues.Add(_value); 

       i++; 
      } 

      Console.WriteLine(_group.GroupName + " " + i.ToString()); 
     } 

     return _lookupGroups; 

私が見ていたものについていくつかの検証のために入れました - 私たちが反復する最初のグループはStatesです。私のカウンターは50と言いますが、私のナビゲーションプロパティは100となり、私たちが持っている施設ごとに50セットずつ(2セットあります)表示されます。私のカウンタが50と言っても、すべてのルックアップ値を取得してナビゲーションプロパティに入れています。また、メタデータファイルのすべてのインクルードを削除しました。

明確にする:私はlookupGroupsに添付されているlookupvaluesを持っています。ルックアップ値は機関に割り当てられます。だから私は状態のルックアップグループの値を取得する場合は、私は50のルックアップ値を取得します。上記のコード。この行を実行すると、_group.InstitutionLookupValues.Add(_value);私のInstitutionLookupValues = 100(機関に関係なくすべてのlookupValuesを取る)。私のカウンターは50を示しています。特定の機関に結びついているかどうかわからない、すべての参照値をどこかで取得しています。

+3

問題の内容がわかりません。あなたのカウンターは何ですか?それは違う数字の問題ですか? –

+0

ありがとうございます - 少し質問を更新しました。 – gevjen

答えて

3

これは、変更されたクロージャにアクセスしていることが原因であると考えています。そうでない場合でも、あなたはいないはずです。ライン

var _values = _lookupValues.Where(x => x.LookupGroupID == _group.LookupGroupID); 

は、おそらくあなたは(それがC#5でない限り)、それはやっていると思う何をしていません。ラムダはデリゲートであり、クロージャは値ではなく変数上で閉じます。これは、コード_group.LookupGroupIDが常に列挙子の最終反復からの最後の値になることを意味します。したがって、参照値は1つの_group.LookupGroupIDにのみフィルタリングされます。

は、ブロックを変更してみてください:

foreach (var _group in _lookupGroups) 
{ 
    var currentGroup = _group;  
    var _values = _lookupValues.Where(x => x.LookupGroupID == currentGroup.LookupGroupID); 

    foreach (var _value in _values) 
    { 
    currentGroup.InstitutionLookupValues.Add(_value); 

    i++; 
    } 

    Console.WriteLine(currentGroup.GroupName + " " + i.ToString()); 
} 

私はそれが問題の原因だかどうかわからないんだけど、とにかく他の奇妙な効果を得ることができます。ループ内に独自の変数を作成することで、生成された列挙変数をクローズすることはありません。

これについては、Eric Lippertの記事をご覧ください:Closing over the loop variable considered harmfulこの問題を認識している人がほとんどいないのは驚くべきことです。 ToList()、または類似を使用して

var _lookupValues = _institutionLookupValueRepository.All().Where(x => x.InstitutionID == _userProfile.InstitutionID); 

はまた、クエリを折りたたむには、おそらく良いアイデアです。そうしないと、_lookupGroupsの各ループに対してこのクエリを再評価することになります。これは、クエリがデータベースに対してであるか、ループが大きい場合にパフォーマンスが低下する可能性があります。

+1

+1:素晴らしい分析! – Slauma

+0

それは素晴らしい分析です - ありがとう - 私はこれを試し、報告してくれます、ありがとう。 – gevjen

+0

このコードの変更でも同じ結果が得られます。最初のlookupGroupを実行したときにナビゲーションプロパティの100の状態が表示されます。 – gevjen