不能多次向字典添加相同的键

时间:2014-10-20 19:43:24

标签: c# asp.net-mvc entity-framework dictionary

这是我的代码:

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

我得到的错误是:&#39;已经添加了具有相同密钥的项目。&#39;这是因为有时会重复DueDate值。我的问题是,如果密钥已存在于字典中,如何保持密钥的添加?

2 个答案:

答案 0 :(得分:1)

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

您是否可以仅使用自定义代码进行分组?

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

请注意,我接受了多余的OrderBy和第二次ToDictionary调用 - 我假设您正在尝试“排序”字典,因为没有订购普通字典而无法正常工作。

答案 1 :(得分:0)

您获得重复的密钥,因为有两种方法可以将空字符串作为键,空组或空日期。副本将始终为空字符串。我想知道你是否真的打算在组空时将空字符串作为键。无论如何,没有必要,您可以随时过滤空组。

首先通过数据库引擎按日期(包括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永远不会为空,它始终为Nullable<DateTime>,有或没有值。

旁注:您会注意到EF不会生成SQL group by语句,因为SQL语句是“破坏性的”#34;它只返回分组列和聚合数据,而不是LINQ GroupBy 返回的单个记录。出于这个原因,如果将AsEnumerable放在.GroupBy之前,生成的SQL非常臃肿,可能可以提高性能。