2011-01-09 72 views
2

我目前正在開發一個論壇。我是LINQ和EF的新手。在我的論壇中,我有一個顯示屏,首先顯示最近話題的主題列表。LINQ to Entities關於orderby和null集合的問題

問題是「最近的」與主題的回覆有關。所以我不想按主題的發佈日期排列列表,而是想按主題的最後回覆的發佈日期排列列表。所以具有較新回覆的主題回到列表頂部。如果我知道每個主題都至少有一個回覆,這很簡單;我只是這樣做:

var topicsQuery = from x in board.Topics 
        orderby x.Replies.Last().PostedDate descending 
        select x; 

但是,在很多情況下,該主題沒有答覆。在這種情況下,我想使用主題的發佈日期。在主題沒有回覆的情況下,我的linq查詢中是否有一種方法可以通過x.PostedDate訂購?我對此感到困惑,任何幫助將不勝感激。使用上述查詢,由於假設有回覆的x.Replies.Last(),它會打斷沒有回覆的主題。 LastOrDefault()不起作用,因爲我需要訪問也假定回覆存在的PostedDate屬性。

在此先感謝您的任何見解。

+0

我可以通過獲取所有回覆,遍歷它們並使用if語句來確定是否有答覆並以這種方式構建新列表來實現。但是如果有一種方法可以在查詢中完成而不是每次都循環遍歷它們,那就太棒了。 – Chev 2011-01-09 05:07:03

回答

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); 
+0

我愛你。你爲我節省了一堆時間。我不知道.Any()和'讓'感謝你+1,並在接下來的時間內讓我接受。 – Chev 2011-01-09 05:15:20

+0

很高興這是有幫助的:) – 2011-01-09 05:16:50

+0

你可能提供一個例子,你將如何在鏈式linq中使用let關鍵字?就像`.OrderBy(x => x.PostedDate)` – Chev 2011-01-09 05:18:34

0

您是否想過要爲主題數據添加新字段?像LastActivityDate。將其設置爲發佈日期主題,然後每次添加回復時進行更新。

我不是SQL Server專家,但是如果您嘗試執行查詢所要求的操作,您最終可能會忽略您的索引並執行全表掃描。

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 
0

一個典型的論壇有很多讀取和寫入很少,尤其是在這種特殊情況下。因此我會選擇在最後一個字段中緩存LastPostDate。它提供了一些冗餘和更多的編程來保持價值最新,但我認爲在大多數情況下,這是最好的方式。