我目前正在开发一个论坛。我是LINQ和EF的新手。在我的论坛中,我有一个显示,它显示了一个主题列表,其中最新的主题排在前面。
问题是“最近的”是与主题的回复相关的。因此,我不想根据主题的发布日期对列表进行排序,而是希望根据主题的最后回复日期对列表进行排序。因此,具有较新回复的主题将弹回列表的顶部。如果我知道每个主题至少有一个回复,这就相当简单了;我会这样做:
var topicsQuery = from x in board.Topics
orderby x.Replies.Last().PostedDate descending
select x;
然而,在许多情况下,该主题没有回复。在这种情况下,我想使用主题的发布日期。在我的linq查询中,有没有办法在主题没有回复的情况下按x.PostedDate
排序?我被这个搞糊涂了。
使用上面的查询,它在没有回复的主题上中断,因为x.Replies.Last()
假设有回复。LastOrDefault()
无法工作,因为我需要访问PostedDate属性,该属性也假定存在回复。
发布于 2011-01-09 13:13:53
var topicsQuery = from x in board.Topics
let lastActivityDate = x.Replies.Any()
? x.Replies.Last().PostedDate
: x.PostedDate
orderby lastActivityDate descending
select x;
编辑:
为了回答您的意见,linq表达式语法没有显式的'let‘。但是,您可以实现如下所示(使用中间select表达式):
var topicsQuery = board.Topics.Select(x => new {
Topic = x,
LastActivityDate = x.Replies.Any()
? x.Replies.Last().PostedDate
: x.PostedDate
})
.OrderByDescending(p => p.LastActivityDate)
.Select(r => r.Topic)
Edit2:
正如Nicholas所建议的,这可以进一步简化,我们也可以删除中间的select语句。注意,如果没有不同的执行,这是不可能的。
var topicsQuery = board.Topics
.OrderByDescending(x => x.Replies.Any()
? x.Replies.Last().PostedDate
: x.PostedDate);
发布于 2011-01-09 13:20:04
您是否考虑过在主题数据中添加一个新字段?就像LastActivityDate一样。将其初始设置为topics,然后在每次添加回复时更新。
我不是SQL Server专家,但是如果您尝试对查询执行您所要求的操作,您可能会得到一个忽略索引并执行全表扫描的查询。
发布于 2011-01-09 14:16:34
一个典型的论坛有很多读和很少的写,特别是在这个特殊的情况下。因此,我会选择在一个额外的字段中缓存LastPostDate。它提供了一些冗余和更多的编程来保持值的最新,但我认为在大多数情况下这是最好的方法。
https://stackoverflow.com/questions/4637771
复制相似问题