这是我的代码:
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值。我的问题是,如果密钥已存在于字典中,如何保持密钥的添加?
答案 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非常臃肿,可能可以提高性能。