繁体   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