根据 Entity Framework 中的值按某些列分组

Group by some columns depending on values in Entity Framework

我的 Entity Framework 代码中有以下简单语句:

        query = query
                .Where(c => c.NotificationType == NotificationType.AppMessage)
                .GroupBy(c => c.ConversationId)
                .Select(d => d.OrderByDescending(p => p.DateCreated).FirstOrDefault());

它只是根据带有 conversationId 和 select latest 的组来查找最新的 Notification。简单。

然而,如果c.NotificationType == NotificationType.AppMessage,这只是我想要的。如果该列不同于 AppMessage (c.NotificationType <> NotificationType.AppMessage),我只需要该列。我真正想写的是一个神奇的声明,例如:

         query = query
                .Where(c => (c.NotificationType <> NotificationType.AppMessage) 
                || ((c.NotificationType == NotificationType.AppMessage)
                .GroupBy(c => c.ConversationId)
                .Select(d => d.OrderByDescending(p => p.DateCreated).FirstOrDefault()));

但这没有意义,因为 GroupBy/Select 是基于第一个 where 语句。

我该如何解决这个问题?

public class EntityClass
{
    public int NotificationType { get; set; }

    public int ConversationId { get; set; }

    public DateTime Created { get; set; }

    public static EntityClass GetLastNotification(int convId)
    {
        var list = new List<EntityClass>(); // Fill the values

        list = list
            .GroupBy(i => i.ConversationId) // Group by ConversationId.
            .ToDictionary(i => i.Key, n => n.ToList()) // Create dictionary.
            .Where(i => i.Key == convId) // Filter by ConversationId.
            .SelectMany(i => i.Value) // Project multiple lists to ONLY one list.
            .ToList(); // Create list.

        // Now, you can filter it:

        // 0 - NotificationType.AppMessage
        // I didn't get what exactly you want to filter there, but this should give you an idea.
        var lastNotification = list.OrderByDescending(i => i.Created).FirstOrDefault(i => i.NotificationType == 0);
        return lastNotification;
    }
}
  1. 您根据 ConversationId 使用 "GroupBy" 过滤您的列表。接下来,根据结果创建一个字典并只制作一个列表 (SelectMany)。然后,您已经有了一个列表,其中应该只有您想要的具有 ConversationId 的记录。

最后一部分用于过滤此列表 - 您希望最后通知具有特定的 NotificationType。应该工作 :)

最简单的方法是在原始查询的末尾使用 Concat 编写 UNION ALL 查询:

query = query
    .Where(c => c.NotificationType == NotificationType.AppMessage)
    .GroupBy(c => c.ConversationId)
    .Select(d => d.OrderByDescending(p => p.DateCreated).FirstOrDefault())
    .Concat(query.Where(c => c.NotificationType != NotificationType.AppMessage));