0

次のようなテーブルがあります。

 ActionID | ActionTime | ActionType | UserID
    1       3/22/2013        4          8
    2       3/31/2013        1          8
    3       4/12/2013        3          8

各アクションにはいくつかの ActionTime があり、最新のActionTime が何らかの ActionType であるユーザーごとにすべての ActionID を取得したいと考えています。

これは私が持っているクエリですが、テストしているので、期待どおりに動作していません:

var TheActionType = list of bytes (ie. [1, 3, 5])

(from a in MyDC.Actions
 where a.UserID == TheUserID
 where TheActionType.Contains(a.ActionType)
 orderby a.ActionTime descending (//I only want the last ActionTime each user)
 select a.ActionID).ToList();

したがって、ActionType で [4,1] を渡す場合、最後の ActionTime の ActionType は 3 であるため、何も返されません。

基本的に、最初に最新の ActionID を使用して取得し、次にバイトのリストを使用して 2 番目のクエリを実行することで、これをやり直すことができることはわかっていorderbyます.FirstOrDefault().Contains()、1 つのクエリだけでこれを行う方法があるかどうか疑問に思っていました。

ありがとう。

4

1 に答える 1

1

次のようにします。

MyDC.Actions
    .GroupBy(x => x.UserID)
    .Select(g => g.OrderByDescending(x => x.ActionTime)
                  .First())
    .Where(x => TheActionType.Contains(x.ActionType))
    .Select(x => x.ActionID);

これにより、次のことが行われます。

  1. によってアクションをグループ化しますUserID
  2. ユーザーごとに、最高のアクションを選択しActionTimeます。つまり、最も若いアクションを選択します。
  3. 結果は、許可されたアクション タイプのリストによってフィルタリングされます。
  4. ActionID残りのアクションから選択されます。

例: http://ideone.com/KbwPBI

あなたが言ったので、ユーザーIDによるフィルターを削除しました

各ユーザーの最後の ActionTime のみが必要です

したがって、このクエリは、指定されたアクション タイプに一致する場合、各ユーザーの最後のアクション ID を返します。

1 人のユーザーの最新のアクションのみが本当に必要な場合はWhere、前のクエリに単純に追加できます。

MyDC.Actions
    .Where(x => x.UserID == TheUserID)
    .GroupBy(x => x.UserID)
    .Select(g => g.OrderByDescending(x => x.ActionTime)
                  .First())
    .Where(x => TheActionType.Contains(x.ActionType))
    .Select(x => x.ActionID)
    .SingleOrDefault();
于 2013-10-16T09:47:11.443 に答える