- ベストアンサー
LINQで取得したときの順序
- LINQを使用して、ある年月に一番近い大きな日付を1件取得する方法を探しています。
- データをDataTableに全て取得し、LINQで検索する方法を考えています。
- 年月を降順に指定することで、一番近い大きな年月を取得することができるかどうか確認したいです。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
LINQは基本的には遅延評価にメリットを求めたほうがよいと思います。 速度的には列挙体を検索するのとあまり変わらないです。 DataTableにはSelectメソッドがありますことらを利用すればよいのではないでしょうか? まずLINQより早いです。 http://www.yel.m-net.ne.jp/~oss/Tips/ADO/Tips_01007.htm
その他の回答 (2)
- AKARI0418
- ベストアンサー率67% (112/166)
Dim datarecord = (From animal In dt Where animal.Field(Of Date)("年月") <= getCalcDate And animal.Field(Of Date)("年月") >= minCalcDate Order By animal.Field(Of Date)("年月") Descending Select animal) For Each field In datarecord Console.WriteLine(field("年月")) Next ではどうでしょうか?
お礼
試してみましたが効果が得られませんでした。 SQLを何回も発行するほうが何倍も早かったので LINQはあきらめました。 環境と作り方によって変わるので 合っているものを選んでいこうと思います。 何度もお返事ありがとうございました。
- AKARI0418
- ベストアンサー率67% (112/166)
提示していただいたソースであれば、LINQのほうがダントツで早いです、なぜかというと、抽出が実行されていないからです。 LINQは遅延評価を行います、結果を参照されてたときに始めてクエリが実行される仕組みです。 そのため、 XXXXXXX となっている部分を、何か参照するロジックに変更してください。 3回くらい参照するようにすれば、その差は歴然です。 これを解決する方法は、 datarecord.ToList<>などの変換メソッドのどれかを利用しコピーを作成してからアクセスするようにします。 話を戻します。 LINQは遅延評価ですので、参照されるたびに条件式で評価しなおします。 そのため、そのときのDataTableの内容を評価した結果を返してきます。 条件によっては参照するたびに違った結果を出すことも可能というわけです。
補足
早そうな遅延評価を実行させるように プログラムを書き換えました。 でもうまくできませんでした。 「シーケンスに要素が含まれていません」 が表示されます。 Dim getDate As Date 'ある年月 Dim tbData As DataTable 'データ Dim total as Decimal '合計値 tbData にテーブルデータ取得 Dim datarecord = (From animal In tbData Where animal.Field(Of Date)("年月") <= getCalcDate Order By animal.Field(Of Date)("年月") Descending Select animal).First '対象年月分ループ Do Until getCalcDate < 最小日付 total +=datarecord("データ") getCalcDate = (getCalcDate を減らす式) Loop
補足
ありがとうございます。 やってみましたがLINQの方が早く処理が終わりました。 'DataTableにSelect Do Until getCalcDate < minCalcDate 'Dim datarecord = tbData.Select("年月<=#" & getCalcDate & "#", "年月 DESC") '取得した1行目の合計を計算 XXXXXXXX '次の検索する年月の作成 getCalcDate = DateAdd(DateInterval.Minute, 1, getCalcDate) Loop 'LINQで検索 Do Until getCalcDate < minCalcDate Dim datarecord = (From animal In tbData Where animal.Field(Of Date)("年月") <= getCalcDate Order By animal.Field(Of Date)("年月") Descending Select animal).First '取得した1行目の合計を計算 XXXXXXXX '次の検索する年月の作成 getCalcDate = DateAdd(DateInterval.Minute, 1, getCalcDate) Loop LINQをDo Uintilの外に出すと 結果が間違って返ってきます。