我目前正在开发一个论坛。我是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属性,该属性也假设存在回复。
提前感谢任何见解。
答案 0 :(得分:7)
var topicsQuery = from x in board.Topics
let lastActivityDate = x.Replies.Any()
? x.Replies.Last().PostedDate
: x.PostedDate
orderby lastActivityDate descending
select x;
修改强>
要回答您的评论,linq表达式语法没有“让”显式。但是,您可以实现以下相同(使用中间选择表达式):
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:强>
这可以进一步简化,正如尼古拉斯建议的那样,我们也可以删除中间选择语句。注意,如果没有不同的执行,这是不可能的。
var topicsQuery = board.Topics
.OrderByDescending(x => x.Replies.Any()
? x.Replies.Last().PostedDate
: x.PostedDate);
答案 1 :(得分:2)
我无法发表评论。 FWIW,将其视为评论。
var topicsQuery = from x in board.Topics
let lastActivityDate = x.Replies.Any()
? x.Replies.Last().PostedDate
: x.PostedDate
orderby lastActivityDate descending
select x;
您可能想要更改
x.Replies.Last().PostedDate
这个
x.Replies.OrderByDesc( r => r.PostedDate).First().PostedDate
答案 2 :(得分:0)
您是否考虑过为主题数据添加新字段?像LastActivityDate之类的东西。最初将其设置为主题PostedDate,然后在每次添加回复时更新。
我不是SQL Server专家,但是如果您尝试使用查询执行的操作,您可能最终会得到一个忽略索引并执行全表扫描的查询。
答案 3 :(得分:0)
典型的论坛有很多读取和少量写入,特别是在这种特殊情况下。因此,我会选择将LastPostDate缓存在一个额外的字段中。它提供了一些冗余和更多的编程来保持最新值,但我认为在大多数情况下它是最好的方式。