1

簡単なクエリがあります。parentId が null でない最新の行を選択します。LINQ(lambda) と SQL の両方でクエリを作成しました。最新の子を取得しようとしています。必要なデータを視覚化しようとします。

元のデータ:

-------------------------------
- Id - ParentId - CreatedDate -
-------------------------------
-  1 -          -  07/01/2013 -
-  2 -          -  07/01/2013 -
-  3 -          -  07/01/2013 -
-  4 -        1 -  07/02/2013 -
-  5 -        2 -  07/03/2013 -
-  6 -        2 -  07/04/2013 -
-  7 -        1 -  07/05/2013 -
-------------------------------

クエリによって返されるデータ

-------------------------------
- Id - ParentId - CreatedDate -
-------------------------------
-  6 -        2 -  07/04/2013 -
-  7 -        1 -  07/05/2013 -
-------------------------------

これが私が現在試していることです:

SQL:

SELECT a."ParentId", MAX(a."CreatedDate")
FROM "myTable" AS a
WHERE a."ParentId" IS NOT NULL
GROUP BY a."ParentId"

LINQ(ラムダ):

var uniqueChildren = myTable.Where(a => a.ParentId != null)
        .GroupBy(a => a.ParentId)
        .Select(b => new { ParentId = b.Key, CreatedDate = b.Max(t => t.CreatedDate) });

これにより、キー (ParentId) と作成日を含むいくつかの行が返されます。2 つの情報ではなく、行全体を返すようにしたいと考えています。私は同様の質問を検索し、可能な解決策を見つけました:

var q = from n in table
        group n by n.ParentId into g
        select g.OrderByDescending(t=>t.CreatedDate).First();

これは有望に見えるので、PostgreSQL データベースに対して実行すると、VisualStudio から次のエラーが表示されます。

"The method 'First' can only be used as a final query operation. Consider using the method 'FirstOrDefault' in this instance instead."

このメッセージは非常に簡単です。次のように試してみましょう。

var q = from n in table
        group n by n.ParentId into g
        select g.OrderByDescending(t=>t.CreatedDate).FirstOrDefault();

今、私は別のエラーが発生します:

The method or operation is not implemented

ここで休憩が取れないようです。私は先に進み、問題を引き起こさないことがわかっているコマンドを使用して、ずさんな見た目のソリューションをハックしました。

var q2 =
    (from a in myTable
     join b in
         (myTable.Where(a => a.ParentId != null)
                 .GroupBy(a => a.ParentId)
                 .Select(b => new { 
                                     ParentId = b.Key, 
                                     CreatedDate = b.Max(t => t.CreatedDate) 
                                  }))
     on a.ParentId equals b.ParentId
     where a.CreatedDate == b.CreatedDate
     select a);

これで必要なものが取得されましたが、このタスクを達成するためのよりエレガントな方法があると思います。これを行うための代替方法は何ですか? どんな助けでも大歓迎です。

4

1 に答える 1

1

私はおそらく次のようなことをするでしょう:

最新のレコードが最初になるようにすべてのレコードを並べ替え、一番上のレコードを取ります。

var q = (from a in myTable
         where a.ParentId != null
         orderby a.CreatedDate descending
         select a).Take(1).ToList();

次のような SQL を生成する必要があります。

SELECT TOP 1 *
FROM MyTable a
WHERE a.CreatedDate IS NOT NULL
ORDER BY a.CreatedDate DESC

アップデート

ああ、関連する子の各グループの最新の子が必要です。次に、このようなものがうまくいくはずです。Takeメソッドはプロバイダーで機能すると思います。FirstOrDefaultあなたはすでにそれを試したので、実装されていないようです。

var q =
    from t in myTable
    where t.ParentId != null
    group t by t.ParentId into grp
    select grp.OrderByDescending(p => p.CreatedDate).Take(1);
于 2013-07-03T19:44:52.763 に答える