hsim
hsim

Reputation: 2080

Dictionaries: An item with the same key has already been added

In my MVC app I am using 2 dictionaries to populate SelectList for DropDownList. Those dictionaries will be supplied with dates as string and datetime values.

I have this chunk of code for the first dictionary that works just fine:

if (m_DictDateOrder.Count == 0)
{
     m_DictDateOrder = new Dictionary<string, DateTime>();
     m_DictDateOrder =
          m_OrderManager.ListOrders()
                        .OrderBy(x => x.m_OrderDate)
                        .Distinct()
                        .ToDictionary(x => x.m_OrderDate.ToString(), x => x.m_OrderDate);
}

But when I get to the second dictionary:

if (m_DictDateShipped.Count == 0)
{
     m_DictDateShipped = new Dictionary<string, DateTime>();
     m_DictDateShipped = 
          m_OrderManager.ListOrders()
                        .OrderBy(x => x.m_ShippedDate)
                        .Distinct()
                        .ToDictionary(x => x.m_ShippedDate.ToString(), x => x.m_ShippedDate);
}

I get a runtime error on the LINQ request for the second dictionary:

An item with the same key has already been added.

I first though that I add to instantiate a new dictionary (that's the reason for the "new" presence), but nope. What did I do wrong?

Thanks a lot!

Upvotes: 3

Views: 25627

Answers (2)

Amy B
Amy B

Reputation: 110071

You are Distinct'ing the rows, not the dates.

Do this instead:

if (m_DictDateShipped.Count == 0)
{
     m_DictDateShipped = m_OrderManager.ListOrders()
        //make the subject of the query into the thing we want Distinct'd.
        .Select(x => x.m_ShippedDate) 
        .Distinct()
        .ToDictionary(d => d.ToString(), d => d);
}

Don't bother sorting. Dictionary is unordered.


My standard pattern for this (since I have disdain for Distinct) is:

dictionary = source
  .GroupBy(row => row.KeyProperty)
  .ToDictionary(g => g.Key, g => g.First()); //choose an element of the group as the value.

Upvotes: 12

Stefano Altieri
Stefano Altieri

Reputation: 4628

You applied the Distinct to the order, not to the date. Try

m_OrderManager.ListOrders()
                        .OrderBy(x => x.m_ShippedDate)
                        .Select(x =>x.m_ShippedDate)
                        .Distinct()
                        .ToDictionary(x => x.ToString(), x => x);

Upvotes: 8

Related Questions