0

我有一个看起来像这样的表:

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

每个 Action 都有几个 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,然后使用字节列表运行第二个查询来重做此操作orderby.FirstOrDefault().Contains()我想知道是否有一种方法可以仅使用一个查询来执行此操作。

谢谢。

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。

如果您真的只想要单个用户的最新操作,您可以简单地将其添加到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 回答