2012-02-18 3 views
2

3つのLINQクエリを1つに結合できるかどうかを確認しようとしています。私が抱えている問題は、内部LINQステートメントのwhere句にAnonプロパティの値が必要なことです。これはうまくいかないようです。私もLINQステートメントをインライン化しようとしましたが、それはどちらもうまくいきませんでした。Anonタイプのプロパティの1つを使用してAnonタイプでLinqを使用する

誰もこれまでに行ったことはありますか? PlaceNameは、PlaceIDを使用しているときに問題があるものです。

 var Persons = from _person in people select new 
     { 
      ID = _person.Id, 
      Name = _person.Name, 
      Nationality = _person.Nationality, 
      Age = _person.Age, 
      PlaceID = (from _peopleplaces in peoplePlace where _person.Id ==_peopleplaces.PersonId select _peopleplaces.PlaceId).FirstOrDefault(), 
      PlaceName = (from _places in places where _places.Id == PlaceID select _places.Name).FirstOrDefault() 
     }; 

編集:私が午前、実際の問題はPlaceIDが地名のクエリで使用することができないということです、それはそれの下に赤い波線があります。 1つではなく3つのステートメントを使用する理由は、私自身のためです。私はLINQを勉強しています。私ができることとできないことを見たいと思っています。私は3つの別々のセットではなく、1つのセットを使用してPersonsオブジェクトにデータを埋め込むのが見栄えが良いと思っていました。

実際のエラーは、PlaceIDが現在のコンテキストに存在しないことです。

+1

? – JaredPar

+2

なぜ別個の3つのクエリを書かないのですか?それは読みやすく、簡単で、最終的な結果*はおそらくパフォーマンスの面でも同じになります。 – Tigran

答えて

0

たぶん、あなたはletキーワードを探していますか?

var Persons = 
    from _person in people 
    let placeID = 
    (
     from _peopleplaces in peoplePlace 
     where _person.Id == _peopleplaces.PersonId 
     select _peopleplaces.PlaceId 
    ).FirstOrDefault() 
    let placeName = 
    (
     from _places in places 
     where _places.Id == placeID 
     select _places.Name 
    ).FirstOrDefault() 
    select new 
    { 
     ID = _person.Id, 
     Name = _person.Name, 
     Nationality = _person.Nationality, 
     Age = _person.Age, 
     PlaceID = placeID, 
     PlaceName = placeName, 
    }; 

編集:正しく下記@sambomartinとして、あなたは特定の人のためのpeoplePlaceにエントリがない場合に何が起こるかを検討する必要があります。上記のクエリでは、そのような人物はPlaceIDPlaceNamenullの最終結果で返されます。

C#は、intint?の間の等価比較を可能にします。後者がnullの場合、比較は常にfalseと評価されます。したがって、placeIDnullである場合、placesからのエントリはの条件を満たしません(Idフィールドがヌル可能でないと仮定して)。placeNamenullと評価されます。

あなたが最終的な結果では、あなたがwhere句を追加して、クエリを修正することができ、そのような人にしたくない場合は、次の

var Persons = 
    from _person in people 
    let placeID = 
    (
     from _peopleplaces in peoplePlace 
     where _person.Id == _peopleplaces.PersonId 
     select _peopleplaces.PlaceId 
    ).FirstOrDefault() 
    where placeID != null // ensure that the person has an associated place 
    let placeName = 
    (
     from _places in places 
     where _places.Id == placeID 
     select _places.Name 
    ).FirstOrDefault() 
    where placeName != null // ensure that the place appears in the primary table 
    select new 
    { 
     ID = _person.Id, 
     Name = _person.Name, 
     Nationality = _person.Nationality, 
     Age = _person.Age, 
     PlaceID = placeID, 
     PlaceName = placeName, 
    }; 
あなたが持っているどのようなトラブル
+0

私はこれをあなたに与えなければなりませんでした。 – deanvmc

+0

私はあなたを助けてくれてうれしいです。考慮する必要があるのは、チェックなしではわからないということですが、FirstOrDefaultはレコードが見つからない場合はnullを返します。 placeIdが2番目の 'let'がplacesでnullの場合は例外が発生する可能性があります.Idはnullableではありません。 – sambomartin

+0

@Douglasは編集してくれてありがとうございますが、いくつかのオブジェクトを一緒にコレクションに加えることは長年の解決策でした。私は通常、クエリで同じ値を複数回不必要に評価するのを防ぐために「let」を使用します。私はあなたが持っているそれを使用すると思いますか?そうすることに何か利点はありますか? – sambomartin

3

計算されるまでPlaceIdを使用することはできません。それが列挙されたとき。

1つの式で3つのオブジェクトをクエリすることは何もありません。

var people = from p in Persons 
      from ppl in PersonPlaces 
      From pl in Places 
      where p.Id == ppl.PersonId 
      && ppl.PlaceId == pl.Id 
      select new { Name=p.Name, PlaceName=pl.Name} 

申し訳ありませんが、iPadでは難しいです。

第H

サム

+0

DOH!それは私がしたいと思っていたものの、あなたが考えることができないと思っていたものです。 – deanvmc

+0

もちろん、ダグラスの答えによると...もちろんです。一番上のクエリで返す必要があるものによって異なります。 – sambomartin

関連する問題