Generic Dictionary with multiple keys

 
100   96.6
Mar 07, 2010
 
I am building a caching system that holds among others a list of Users. 

Sometimes we access the Users by userId (the primary key).
Sometimes we access the Users by name (a string)

Performance is critical, therefore we currently use two generic dictionaries:
One is Dictionary<int?, User>, the other is Dictionary<string, User>

The issue I am trying to solve is the double maintenance of the User objects.
So, if a User changes, we have to remember to update two dictionaries.

Is there another way to have a "duplicate key" Dictionary without duplicating the values (i.e. Users)?

I found some articles about Tuples<> (also called ClassKeys) but this will not work as it requires all key values when accessing the dictionary.  I only have one at a time (userId or Name).

Of course, we could use a simple LINQ statement against the User list (i.e. .Where( u => u.Name == name)), but the list is very large and performance will not be optimal (or is there a way to build an in-memory index?).

Thanks.



80   96.3
Mar 09, 2010
Hi Hans,

You can create 2 dictionaries to solve your issue like this.

The First one is <UserID, UserObject>, same as yours.
The Second one is <UserName, UserID>, which will save your client's user id and user name.

So in your code you can find UserID by UserName, then find its user object by UserID.

In this case you avoid having to update user object twice when it is changed. But the cost is you have to find UserID first if UserName is given.

I hope this helps.

 2 comments
 
Great answer and spot on! Exactly what I was looking for. --- Hans Overkamp  Mar 19, 2010
 
@Zac Bai , @Hans Overkamp solution is a simple but useful one. An very simple improvement to it is to use for the second dictionary where the VALUE UserObject is actually a pointer to the UserObject in the dictionary. This would increase lookup\read performance by a factor of X or the amount of items in the hash table or dictionary. :) --- Louis M  Jan 26, 2012