3

私はこれにこだわっています。Users2Users と ActivityLog の 2 つのテーブルがあります。ユーザーの友達である Users2Users のリストを検索し、タイムスタンプに基づいて最新のアクティビティをそれぞれ返し、そのタイプを確認したいと考えています。

Users2Users
int UserId
int TypeOfLink
int FriendId

ActivityLog
int Type
int UserId
DateTime Timestamp

私を悩ませているように見えるのは、Timestamp 値ではなく ActivityLog エンティティを取得することです。

私の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 を試すつもりでしたが、Timestamp ではなく 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です。を使用してそれを行うことができますAggregateActivityここでは、Timestampプロパティが次のデフォルト(および最小値)を持つ「null」を作成できると仮定します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、匿名タイプを使用して最新のタイムスタンプと関連するアクティビティを追跡できますが、実行するのは少し面倒です。

于 2012-08-10T14:08:58.007 に答える