簡體   English   中英

按ID可以在第1列或第2列中分組

[英]Grouping by when id can be in column 1 or 2

在我的網站上,成員可以相互發送消息。 這是我的Message類:

public partial class Message
{
    public System.Guid Id { get; set; }
    public System.DateTime DateMsg { get; set; }
    public string SenderId { get; set; }
    public string ReceiverId { get; set; }
    public string Text { get; set; }
}

我想進行查詢,以獲取每次打開的討論的最新消息。 由於我沒有“討論ID”,因此我無法進行“ group by DiscussionId”,然后選擇每個組中的第一個。 我該怎么辦?

public IEnumerable<Message> Get_DiscussionsFor(string userId)
        {
            List<Message> list;
            using (var context = new ModelContainer())
            {
                IQueryable<Message> dbQuery = context.Set<Message>();               

                list = dbQuery
                    .AsNoTracking()
                    .Where(m => m.SenderId.Equals(userId) || m.ReceiverId.Equals(userId))
                    .OrderByDescending(m => m.DateMsg)                        
                    .ToList<Message>();
            }
            return list;
        }

好吧,這可能會奏效,盡管不會很快。

這是查詢的第一部分:

            var list1 = dbQuery
                .AsNoTracking()
                .Where(m => m.SenderId.Equals(userId) || m.ReceiverId.Equals(userId));

我將創建另一個查詢,該查詢將創建一個匿名類型,將消息和其他用戶的ID封裝起來。

            var senderFirst = list1
                .Where(m => m.SenderId.Equals(userId))
                .Select(
                 m => {
                   Message = m,
                   OtherUser = m.ReceiverId
                 });

我正在創建另一個,這次是我們想要的用戶是接收者,另一個用戶是發送者的用戶:

          var receiverFirst = list1
              .Where(m => m.ReceiverId.Equals(userId))
              .Select(
                m => {
                   Message = m,
                   OtherUser = m.SenderId,
                });

我現在將它們串聯起來。 我之所以這樣做,是因為它們具有完全相同的屬性,相同的類型和相同的名稱:在后台,它們是相同的匿名類型。

            var list2 = senderFirst.Concat(receiverFirst);

結果,每條涉及您想要的用戶的消息將與標識為OtherUser的其他用戶一起出現。 請注意,我們根本沒有更改Message對象:它仍然存在,並具有SenderIdReceiverId的正確值。 我們只是將它包裝在帶有附加元數據的另一個對象中。

您說過,涉及給定兩個用戶的任何消息都在同一討論中。 因此,我們現在可以通過討論通過OtherUser的分組來模擬分組:

             var list3 = list2.GroupBy(m => m.OtherUser);

現在,我們對消息進行了分組。 現在,您可以對每個組進行排序並選擇最終消息。

             var list4 = list3
                 .Select(g => g.OrderByDescending(m => m.Message.DateMsg).First());

現在,您有了List<Message> ,因為您的Message對象仍在其中,可以從封裝中彈出:

             var list = list4
                 .Select(m => m.Message)
                 .ToList();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM