2012-08-10 57 views
2

我堅持這一點。我有兩個表:Users2Users和ActivityLog。我想查找用戶朋友Users2Users的列表,並根據其時間戳返回其最新活動,然後檢查它是什麼類型。返回實體與最新的時間戳匹配userId LINQ

Users2Users 
int UserId 
int TypeOfLink 
int FriendId 

ActivityLog 
int Type 
int UserId 
DateTime Timestamp 

似乎困擾我的事情是獲取ActivityLog實體,而不是它的Timestamp值。

我的好友列表查詢看起來是這樣的:

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 
} 

回答

5

您可以通過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來做到這一點。在這裏,我假設你能夠創建一個「空」 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,您可以使用匿名類型來跟蹤最新的時間戳記和相關活動,但要做的工作稍微繁瑣一些。

+0

感謝您的支持。我想在你的第一個代碼中,哪裏錯過了lambda?在哪裏(a => a.UserId == user.UserId) – testpattern 2012-08-10 14:18:13

+0

@testpattern:感謝您指出。現在應該修好了。 – 2012-08-10 14:30:38

+0

馬丁,我稍後再試一下,並告訴你。謝謝你的幫助。 – testpattern 2012-08-10 16:44:16