简体   繁体   English

根据某些列进行分组,具体取决于Entity Framework中的值

[英]Group by some columns depending on values in Entity Framework

I have the following simple statement in my Entity Framework code: 我的实体框架代码中包含以下简单语句:

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

It simply finds the latest Notification based on a group by with conversationId and select latest. 它只是基于具有sessionId的组来查找最新的Notification ,然后选择Latest。 Easy. 简单。

However, this is ONLY what I want if c.NotificationType == NotificationType.AppMessage . 但是,这仅是我想要的,如果c.NotificationType == NotificationType.AppMessage If the column is different than AppMessage ( c.NotificationType <> NotificationType.AppMessage ), I just want the column. 如果该列与AppMessage( c.NotificationType <> NotificationType.AppMessage )不同,则只需要该列。 What I truly Want to write is a magical statement such as: 我真正想写的是一个神奇的陈述,例如:

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

But this doesn't make sense because the GroupBy/Select is based on the first where statement. 但这没有意义,因为GroupBy / Select基于第一个where语句。

How do I solve this? 我该如何解决?

The simplest way is to compose UNION ALL query using Concat at the end of your original query: 最简单的方法是在原始查询的末尾使用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));
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. you filter your list with "GroupBy" based on ConversationId. 您可以根据ConversationId使用“ GroupBy”过滤列表。 Next, create a dictionary from the result and make only one list (SelectMany). 接下来,从结果中创建字典并仅列出一个列表(SelectMany)。 Then, you already have one list where should be only records with ConversationId you want. 然后,您已经有了一个列表,其中仅应包含具有所需ConversationId的记录。

Last part is for filtering this list - you wanted to last notification with certain NotificationType. 最后一部分是用于过滤此列表的-您希望最后使用某些NotificationType进行通知。 Should be working :) 应该工作:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM