3

我坚持这一点。我有两个表: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 实体而不是时间戳?

// 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
}
4

1 回答 1

8

您可以按顺序排列条目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

如果你不能创建一个“空”活动作为种子,Aggregate你可以使用匿名类型来跟踪最新的时间戳和相关的活动,但这样做会稍微乏味一些。

于 2012-08-10T14:08:58.007 回答