Key2020
Key2020

Reputation: 45

Item has already been added. Key in dictionary c#

I am receiving an error in the

var passwords

The error is Item has already been added.

Key in dictionary: '[email protected]' Key being added: '[email protected]'

int totalrecords= 2;

if (encrypted == null || hashedProvider == null) 
    return;

var passwords = encrypted
  .GetAllUsers(0, int.MaxValue, out dontCare)
  .Cast<MembershipUser>()
  .Where(u => u.IsLockedOut == false && u.IsApproved == true)
  .ToDictionary(u => u.UserName, u => u.GetPassword());

Is there a way resolve this issue?

Upvotes: 0

Views: 1536

Answers (2)

Harald Coppoolse
Harald Coppoolse

Reputation: 30454

You want to use the MemberShupUser.UserName as key in the Dictionary.

The error message says that you are trying to add a Key that is already in the Dictionary.

Apparently your Usernames are not unique.

To check this before you are creating the Dictionary, make groups of users that have the same UserName, and count the number of UserNames.

var usersToAddTodictionary = encrypted
   .GetAllUsers(0, int.MaxValue, out totalrecords)           
   .Cast<MembershipUser>();
IEnumerable<string> duplicateUserNames = usersToAddToDictionary

    // make groups of MemberShipUsers that have the same UserName
    .GroupBy(memershipUser => membershipUser.UserName,

        // parameter resultSelector: for every UserName and all MemberShipUsers that have
        // this UserName, make one new:
        (userName, memberShipUsersWithThisUserName) => new
        {
             UserName = userName,
             HasDuplicates = memberShipUsersWithThisUserName.Skip(1).Any(),

        });

To detect whether the UserName has duplicates I check if there is more than one. This is just an efficiency that I don't have to enumerate all elements if after the 2nd one I already know that this UserName has duplicates.

Continuing the LINQ: keep only those groups that has duplicates:

    .Where(group => group.HasDuplicates);
    .Select(group => group.UserName);

So before you make the Dictionary, you could decide what to do with members that have too many passwords.

You could keep just one element, but which password should you keep?

It is better to check if the user is already registered before he is added to your encrypted database.

Upvotes: 0

TheGeneral
TheGeneral

Reputation: 81493

You can simply group the results and select the first

var passwords = encrypted
  .GetAllUsers(0, int.MaxValue, out dontCare)
  .Cast<MembershipUser>()
  .Where(u => u.IsLockedOut == false && u.IsApproved == true)
  .GroupBy(x => x.UserName)
  .ToDictionary(u => u.Key, y => y.First().GetPassword());

Upvotes: 1

Related Questions