根据实体框架中的值对某些列进行分组

时间:2017-10-13 09:41:54

标签: c# entity-framework entity-framework-6 c#-5.0

我的实体框架代码中有以下简单声明:

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

它只是通过conversationId找到基于组的最新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语句。

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

最简单的方法是在原始查询结束时使用UNION ALL撰写Concat查询:

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

答案 1 :(得分:0)

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记录。
  2. 最后一部分用于过滤此列表 - 您希望使用某些NotificationType上次通知。应该工作:)