views:

164

answers:

2

So I've been advised a few times to disable lazy loading when building an application with the above frameworks, and that ToList() will force the queries in my repository to execute. I was told that I would avoid certain "traps" I might run into if I used AsEnumerable().

On a recent question, however, I included a bunch of ToList()s in my code examples, and startled a number of people that assured me IEnumerable is much better to return.

I'm thoroughly confused now, to say the least.

Should I be returning IEnumerable in my repository, then converting them to List in my view models? Should I use ToList() straightaway in my repository like I was before? Was I suppose to leave deferred execution enabled in the first place?

Jiminy Christmas...

Edit: So, being that I disabled lazy loading, based on earlier advice, should I then re-enable it, return IEnumerable / IQueryable from my repository, and convert the collection to a List in my view models, if needed?

One of the answers below associates IEnumerable with eager execution, while I was under the impression that only ToList() would force immediate execution of the query.

I stumbled across this, this, and this that all contain some interesting discussion related to this question.

+5  A: 

Call ToList(), returning an IEnumerable in your repository, if:

  1. You want to control the output set provided to the consumer (i.e. you don't want them to run queries on it), and
  2. You don't mind eager execution.

Return IQueryable, or IEnumerable via AsEnumerable(), in your repository if:

  1. You don't mind your consumers running queries on the output set, and
  2. You want deferred execution.

See Also
http://thinkbeforecoding.com/post/2009/01/19/Repositories-and-IQueryable-the-paging-case

Robert Harvey
I suppose part of my question included whether or not I should be forcing eager execution with the given combination of frameworks, as some have advised.
PolishedTurd
In addition to the factors I've already mentioned, forcing eager execution may actually cause performance issues; the entire data set is returned in one go, even though the consumer might not actually need all of the data.
Robert Harvey
Interesting article. Thank you.
PolishedTurd
You mentioned that disposing the context is something you never do? Is my use of using() superfluous?
PolishedTurd
Aside from sorting and paging, `IQueryable<T>` allows you to project onto presentation models without worrying about loading strategies. It "just works".
Craig Stuntz
I thought that if something implements `IQueryable<T>` and you return it as `IEnumerable<T>` the underlying object is still `IQueryable<T>` and therefore retains delayed execution etc...? Hence the reason to return `IList<T>`.
Charlino
@Charlino: `IQueryable` inherits from `IEnumerable`, so no, an `IEnumerable` is not an `IQueryable`. However, see my edit.
Robert Harvey
This edit makes much more sense now.
PolishedTurd
I'm aware that `IEnumerable` isn't an `IQueryable` I was just pointing out that simply returning `IEnumerable` alone isn't enough. Your edit does clear it up, although I would add that `AsEnumerable()` isn't required seeings that `IQuerable` inherits from `IEnumerable` already.
Charlino
A: 

This blog entry has the details of exactly the problem you are describing. However, read Craig Stuntz's comment on it before taking any action.

Alex
Hmm, the blog entry states that disposing the DataContext (something I never do) can cause data loss, fixes it by running ToList(), and then states that, if you don't dispose of the data context, you won't have the problem in the first place.
Robert Harvey
It talks about IQueryable and IEnumerable and their impact on deferred query execution.
Alex
Dont agree with the article, but agree with Craig Stunz's comment. We don't wrap the DC in a using, we handle it all using DI (context is HTTP Context Scoped, and disposed of explcitly when HTTP context is disposed of)
RPM1984
I've been looking into the possibility of implementing a context-scoped context since reading some of the responses to this question.
PolishedTurd