返回具有与userId LINQ匹配的最新时间戳的实体

时间:2012-08-10 14:00:31

标签: c# asp.net-mvc-3 linq-to-entities

我被困在这上面了。我有两个表:Users2Users和ActivityLog。我想查找作为用户朋友的Users2Users列表,并根据其时间戳返回每个最新活动,然后检查它是什么类型。

Users2Users
int UserId
int TypeOfLink
int FriendId

ActivityLog
int Type
int UserId
DateTime Timestamp

似乎令我不安的是获取ActivityLog实体而不是Timestamp值。

我的friendList查询如下所示:

var friendList = (from u in db.Users2Users
where u.UserId == userId || u.FriendId == userId
&& u.TypeOfLink == 2 // confirmed as friend
orderby u.User.ScreenName ascending
select u).Distinct().ToList();

之后我将尝试foreach,但是如何返回ActivityLog实体而不是Timestamp?

// get their last activity
foreach (var user in domusers)
{
    var act = (from a in db.ActivityLogs
    where a.UserId == user.UserId
    select a.Timestamp).Max();
    // other stuff
}

1 个答案:

答案 0 :(得分:6)

您可以按Timestamp订购参赛作品,然后选择第一个元素:

var act = db.ActivityLogs
  .Where(a => a.UserId == user.UserId)
  .OrderByDescending(a => a.Timestamp)
  .FirstOrDefault();

或使用查询语法:

var act = (from a in db.ActivityLogs 
where a.UserId == user.UserId
orderby a.Timestamp descending
select a).FirstOrDefault();

请注意,如果源集合中没有元素,您将获得null结果。

使用OrderByDescending稍微有点无效,因为它会对所有活动进行排序。在集合上执行单次传递并找到具有最新Timestamp的元素更有效。您可以使用Aggregate执行此操作。在这里,我假设您能够创建一个“null”Activity,其中Timestamp属性具有DateTime的默认值(和最小值):

var nullActivity = new Activity(); // nullActivity.Timestamp == DateTime.MinValue
var activity = db.ActivityLogs
   .Where(a => a.UserId == user.UserId)
   .Aggregate(
     nullActivity,
     (accumulate, value) => value.Timestamp >= accumulate.Timestamp ? value : accumulate
   );
if (activity != nullActivity)
  // The latest activity was found

如果您无法创建“null”活动作为Aggregate的种子,则可以使用匿名类型来跟踪最新的时间戳和相关活动,但这样做会稍微繁琐。 / p>