5

JulieLermanのDbContext本のBAGAコードを使用しています。LINQで次のSQLクエリを再作成し、結果をリストコレクションに入れたいのですが、問題が発生しています。 http://learnentityframework.com/downloads/

SELECT * FROM baga.Locations d
LEFT JOIN Lodgings l ON d.LocationID = l.destination_id
WHERE d.Country = 'usa'
AND (l.MilesFromNearestAirport > 5 or l.MilesFromNearestAirport is null)

したがって、英語で、米国内のすべての場所(目的地)を取得し、MilesFromNearestAirport>5の関連するすべての宿泊施設を含めます。

構文はコンパイルされませんが、私は以下のようなものを望んでいました

var dests = context.Destinations
  .Where(d => d.Country == "USA" && d.Lodgings.Where(l => l.MilesFromNearestAirport > 5))
  .Select(d => d)
  .ToList();

何か案は?

4

3 に答える 3

7

@Sampathが言うように、これは通常ナビゲーションプロパティを使用して行われますが、彼のコードはあなたが望むことを正確に実行していないと思います。これは(私が思うに)もっと近いです:

var dests = context.Destinations
           .Where(d => d.Country == "USA")
           .Select(d => 
               new { d,
                     RemoteLodgings = d.Lodgings
                         .Where(l => l.MilesFromNearestAirport > 5)}
           .ToList();

しかし、私があなたの要求を手紙に持っていくならば、それはあなたが望むことをまだしません。宿泊施設が含まれている場所、つまりナビゲーションプロパティが部分的に読み込まれている場所が必要です。これは、エンティティをシリアル化して1つのパッケージで(Web)クライアントに送信する場合に便利です。(ただし、上記の方法でも問題ありません)。

ただし、部分的にロードされたナビゲーションプロパティを使用してコレクションを作成することは可能です。

この本の40ページには、単一のエンティティのナビゲーションプロパティを部分的にロードする方法が示されています(要するに:context.Entry(entity).Collection(e => e.Children).Query().Where(condition)。しかし、前述のように、これは1つのインスタンスにすぎません。エンティティのコレクションに対してこれを行うのは最善の方法ではありません。

面白いのは(私の同僚が見つけたように)、必要なコレクション要素を個別にコンテキストにロードすることで、エンティティのコレクションに対して簡単に実行できることです。

var lodgings = context.Lodgings
              .Where(l => l.MilesFromNearestAirport > 5 
                       && l.Destination.Country == "USA")
              .ToList();

ここでループするcontext.Destinations.Where(d => d.Country == "USA")と、宿泊施設に「」がロードされていることがわかります>5。おそらく、この時点でEFが関係の修正を実行したためです。(遅延読み込みはナビゲーションプロパティを完全に読み込むため、遅延読み込みは無効になっています)。

編集(あなたのコメントの後)
あなたがそれがちょっとしたハックだと言うとき、私はこれ以上同意できませんでした。実は、そもそもそのことを言うのを忘れていました。問題は、コードの目的を知らない誰かが遅延読み込みをアクティブにすると、メカニズム全体が崩壊することです。明らかではない方法で状態に依存するコードは好きではありません。だから私はいつも最初のアプローチを好むでしょう。

于 2012-12-16T19:39:09.080 に答える
2

通常、これは、エンティティを取得するときに読み込まれるナビゲーションプロパティを使用して行われます。

ただし、これは次の方法でも実行できます。

(from d in baga.Locations
 from l in Lodgings
 where (d.LocationID == l.destination_id)
 where (d.Country = 'usa' && (l.MilesFromNearestAirport > 5 || l.MilesFromNearestAirport == null))
 select d)
 .ToList();

これがお役に立てば幸いです。

于 2012-12-16T17:06:44.197 に答える
1

LINQジョインを使ってみませんか?

 var res = from d in context.Destinations
           join l in context.Lodgings on d.LocationID equals l.destination_id
           where (l.MilesFromNearestAirport > 5 || l.MilesFromNearestAirport == null)
                 && d.Country = "usa"
           select new {
                     Destination = d,
                     Location = l
                  }
于 2012-12-17T08:22:04.017 に答える