Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hashset vs. IQueryable

Recently I was working on implementing a small snippet that caches my results and the way I was doing it was using a Dictionary as follows:

 private Dictionary<ID, IQueryable<Results>> _simpleCache;

The idea was to search for all the results that have the id specified by 'ID' and if the Dictionary contains the key == id, we simply search through the values present in the IQueryable instead of making a database trip.

I was going over this piece of logic this morning and I was thinking about replacing the IQueryable with HashSet as follows:

private Dictionary<ID, HashSet<Results>> _simpleCache;

Is making this change advisable?

like image 915
sc_ray Avatar asked Feb 24 '10 23:02

sc_ray


1 Answers

Yes, it is. Generally, IQueryable<T> implies that you are using a data source provider which is queried each time the queryable is enumerated (of course, this isn't always the case, as you can call AsQueryable extension method on an IEnumerable<T> which will give you an IQueryable<T> implementation over the IEnumerable<T> implementation).

To that end, storing the IQueryable<Results> in a dictionary doesn't actually prevent any hits to the data source when you enumerate through it a second time. It will make a request to the data provider every time you enumerate through it.

Because of this, you typically want to materialize the results on the client side, usually calling the ToList or ToArray extension methods, and then using IEnumerable<Results> or Results[] as the TValue type parameter of your dictionary.

Note that you could use a HashSet<T> to store your objects, but you have to make sure that you implement IEquatable<T> and override GetHashCode so that the default equality comparer will perform a comparison on the ID instance exposed by the Results type, either that, or you have to provide an IEqualityComparer<T> implementation that will do the same thing. It's more than likely that you are using designer-generated code, and it will not do this for you, and your objects will have equality determined by reference, not by value.

like image 98
casperOne Avatar answered Sep 21 '22 21:09

casperOne