-1

テスト用のlinqを作成しましたが、特別なことは何もありません:

        public IEnumerable<Flight> GetActiveFlights(IEnumerable<Flight> flights)
    {
        return from flight in flights
            from segments in flight.Segments
            where segments.DepartureDate > DateTime.Now
            select new Flight
            {
                Segments = flight.Segments
            };
    }

そして、飛行中の各セグメントの各行に複数の行を返します=/

例:

フライトリストには次のものがあります: セグメント 1、セグメント 2

セグメント 1 のリスト: 出発、到着 セグメント 2 のリスト: 出発、到着

それ以外の:

出発: 2.9.2013 4:50:51、到着: 2.9.2013 7:50:51;

出発: 2.9.2013 5:50:51、到着: 2.9.2013 7:50:51; 出発: 2.9.2013 8:50:51、到着: 2.9.2013 10:50:51;

私は得る:

出発: 2.9.2013 4:50:51、到着: 2.9.2013 6:50:51;

出発: 2.9.2013 5:50:51、到着: 2.9.2013 7:50:51; 出発: 2.9.2013 8:50:51、到着: 2.9.2013 10:50:51;

出発: 2.9.2013 5:50:51、到着: 2.9.2013 7:50:51; 出発: 2.9.2013 8:50:51、到着: 2.9.2013 10:50:51;

つまり、飛行中のセグメントが複数ある場合は、2 つのレコードが取得されます。アドバイスをいただければ幸いです。

4

2 に答える 2

6

そして、飛行中の各セグメントの各行に複数の行を返します=/

はい、これはクロス結合が効果的に行われているためです。

from flight in flights
from segments in flight.Segments

私はあなたがこのようなものがもっと欲しいと思う:

from flight in flights
where flight.Segments.Any(seg => seg.DepartureDate > DateTime.Now)
select new Flight { Segments = flight.Segments };

または、将来のセグメントのみを含めたい場合:

from flight in flights
let futureSegments = flight.Segments
                           .Where(seg => seg.DepartureDate > DateTime.Now)
                           .ToList()
where futureSegments.Any()
select new Flight { Segments = futureSegments };

このToList()呼び出しにより、flight.Segmentsがフライトごとに 1 回だけ評価されることに注意してください。同じことが最初のクエリに対して実行される可能性がありますが、flight.Segments 実際に複数回評価できない場合を除き、それほど重要ではありません。

余談ですが、DateTime.Nowの使用には細心の注意を払ってください。これは常に現地時間であるためです。これは、タイム ゾーンの境界を自然に越えるフライトに特に関係します。可能であれば、すべてを UTC に保つことをお勧めします。

于 2013-08-30T15:57:35.143 に答える
1

これは、フィルター内の各子セグメントも反復処理しているためです。これにより、レコードがどこから来ている可能性が高い結合が発生します。

あなたが望むクエリはこれだと思います

return from flight in flights
       where flight.Segments.Any(x => x.DepartureDate > DateTime.Now)
       select flight;
于 2013-08-30T15:58:16.397 に答える