不能多次将同一关键字添加到字典中

本文关键字:添加 字典 关键字 不能 | 更新日期: 2023-09-27 18:27:09

这是我的代码:

IEnumerable<ServiceTicket> troubletickets = db.ServiceTickets.Include(t => t.Company).Include(t => t.UserProfile);
var ticketGroups = new Dictionary<string, List<ServiceTicket>>();
ticketGroups = troubletickets
                .GroupBy(o => o.DueDate).ToDictionary(
                    group => {
                        var firstOrDefault = @group.FirstOrDefault();
                        return firstOrDefault != null
                            ? firstOrDefault.DueDate.HasValue
                                ? firstOrDefault.DueDate.Value.ToShortDateString()
                                : ""
                            : "";
                    },
                    group => group.ToList()
                ).OrderBy(g => g.Key).ToDictionary(g => g.Key, g => g.Value);

我得到的错误是:"已经添加了具有相同密钥的项。"这是因为DueDate值偶尔会重复。我的问题是,如果字典中已经存在密钥,我如何避免添加该密钥?

不能多次将同一关键字添加到字典中

似乎是按一个值(DueDate值)分组,但使用不同的值作为字典键。

你可以不只是使用自定义代码进行分组吗?

ticketGroups = troubletickets
                .GroupBy(o => o.DueDate.HasValue
                                ? o.DueDate.Value.ToShortDateString()
                                : "")
                .ToDictionary(g => g.Key, g => g.ToList());

请注意,我接受了多余的OrderBy和第二个ToDictionary调用——我假设您试图对字典进行"排序",因为普通字典无法排序,所以无法正常工作。

您会得到重复的键,因为有两种方法可以获得空字符串作为键,要么是空组,要么是空白日期。重复项将始终为空字符串。我想知道当组为空时,您是否真的打算获得一个空字符串作为关键字。无论如何,这是不必要的,你可以随时过滤空的组以后。

通过数据库引擎按日期(包括null)分组更容易,然后在内存中应用字符串格式:

IQueryable<ServiceTicket> troubletickets = db.ServiceTickets
                                             .Include(t => t.Company)
                                             .Include(t => t.UserProfile);
Dictionary<string, List<ServiceTicket>> ticketGroups = 
                troubletickets
               .GroupBy(ticket => ticket.DueDate)
               .AsEnumerable() // Continue in memory
               .ToDictionary(g => g.Key.HasValue 
                                        ? g.Key.Value.ToShortDateString() 
                                        : string.Empty,
                                  g => g.Select(ticket => ticket));

现在按Key值进行分组,而不是按组中的First元素进行分组。Key从不为null,它始终是Nullable<DateTime>,无论是否有值。

附带说明:您会注意到EF不会生成SQL group by语句,这是因为SQL语句是"破坏性的":它只返回分组列和聚合数据,而不是LINQ GroupBy返回的单个记录。因此,生成的SQL非常臃肿,如果将AsEnumerable放在.GroupBy之前,则可能会增强性能。