views:

37

answers:

3

Most will recommend caching as a list. I know that is a solution and may be the one I go with. But, what if one wants to be able to treat a cached linq-to-sql with full IQueryable (IEnumerable?) functionality?

If one does try to cache the raw result, an error "Query results cannot be enumerated more then once".

So, to make clear my questions are:

  1. Is the hashcode for Lists, IQueryable, and IEnumerable unique?
  2. If I want to cache the linq-to-sql result safely AND provide for maximum functionality afterward, how can I do that?
+1  A: 

But, what if one wants to be able to treat a cached linq-to-sql with full IQueryable (IEnumerable?) functionality?

The class List<T> implements IEnumerable<T> and you can query it using LINQ if you wish.

Most will recommend caching as a list.

I'd say it depends on what you plan to do with your cached data. A List<T> is fine in many cases. If you want to have fast lookups based on a unique key you might be better off storing the cached data in a Dictionary<TKey, TValue> instead.

Mark Byers
+1  A: 

Once you have cached an IEnumerable, it is a "hydrated" list that is still queryable itself. The AsQueryable() method can be used to query against the subset of records that are populated into the list:

IEnumerable foo = from o in ctx.MyObjects
                  select o;

foo.ToList();

IEnumerable bar = from f in foo.AsQueryable()
                  select f;

Here is some more good information on using AsQueryable(): http://weblogs.asp.net/zeeshanhirani/archive/2008/07/31/using-asqueryable-with-linq-to-objects-and-linq-to-sql.aspx

Dave Swersky
@Dave Thanks. Here is another good one http://www.weirdlover.com/2010/05/11/iqueryable-can-kill-your-dog-steal-your-wife-kill-your-will-to-live-etc/
Curtis White
The `foo.ToList()` you have there won't do anything useful. Is it there for a reason?
Mark Byers
@Dave Any idea/color on how the gethashcode() works for list type?
Curtis White
@Mark: The call to ToList() will actually execute the query and populate the list. Until then it's just an expression tree.
Dave Swersky
@Curtis: The GetHashCode method would work on a List or List<T> the same as any other type. The default hashing algorithm does some introspection into the state of the object (the fact that it's a list is irrelevant) and combines that with the type of the object to generate a hash that may be used to uniquely identify that *instance* of the list object *for that process.* An identical instance (by state) in a different process can generate a different hash.
Dave Swersky
A: 

Exactly what are you caching? An IQueryable isn't a result (a query is a question, not an answer).

Further, an IEnumerable isn't a thing, it's merely a description. There must be some underlying real data structure (like a List or array)

James Curran