77

タイトルが示すように、include と組み合わせて where 句を実行する方法を探しています。

私の状況は次のとおりです。私は、コードのにおいがいっぱいの大きなアプリケーションのサポートを担当しています。コードを変更しすぎるとどこでもバグが発生するため、最も安全な解決策を探しています。

オブジェクト Bus とオブジェクト People があるとしましょう (Bus にはナビゲーション プロップ コレクションの People があります)。私のクエリでは、起きている乗客のみを含むすべてのバスを選択する必要があります。これは単純なダミーの例です

現在のコードでは:

var busses = Context.Busses.Where(b=>b.IsDriving == true);
foreach(var bus in busses)
{
   var passengers = Context.People.Where(p=>p.BusId == bus.Id && p.Awake == true);
   foreach(var person in passengers)
   {
       bus.Passengers.Add(person);
   }
}

このコードの後、コンテキストが破棄され、呼び出し元のメソッドで結果のバス エンティティが DTO クラス (エンティティの 100% コピー) にマップされます。

このコードは、No-Go である DB への複数の呼び出しを引き起こすため、MSDN ブログでこの解決策を見つけました。

これは結果をデバッグするときにうまく機能しましたが、エンティティが DTO にマップされているとき (AutoMapper を使用)、コンテキスト/接続が閉じられており、オブジェクトを読み込めないという例外が発生します。(コンテキストは常に閉じられており、これを変更することはできません:( )

そのため、選択した乗客が既に読み込まれていることを確認する必要があります (ナビゲーション プロパティの IsLoaded も False です)。Passengers コレクションを調べると、カウントも例外をスローしますが、フィルタリングされたオブジェクトを含む「ラップされた関連エンティティ」と呼ばれるコレクションの Passegers にもコレクションがあります。

これらのラップされた関連エンティティをコレクション全体にロードする方法はありますか? (これはアプリケーション全体で使用されるため、automapper マッピング構成を変更することはできません)。

Active Passengers を取得する別の方法はありますか?

どんなヒントでも大歓迎です...

編集

データが熱心にロードされていないため、Gert Arnold の回答は機能しません。しかし、それを単純化して、ロードされている場所を削除すると。どちらの場合も、execute sql はすべての乗客を返すため、これは非常に奇妙です。したがって、結果をエンティティに戻すときに問題が発生するはずです。

Context.Configuration.LazyLoadingEnabled = false;
var buses = Context.Busses.Where(b => b.IsDriving)
        .Select(b => new 
                     { 
                         b,
                         Passengers = b.Passengers
                     })
        .ToList()
        .Select(x => x.b)
        .ToList();

編集2

多くの苦労の末、ゲルト・アーノルドの仕事の答えです!Gert Arnold が示唆したように、Lazy Loading を無効にして OFF のままにする必要があります。前の開発者は遅延読み込みが好きだったので、これはアプリケーションにいくつかの追加の変更を要求します -_-

4

5 に答える 5