15

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.

Community
  • 1
  • 1
asfsadf
  • 3,822
  • 7
  • 31
  • 41

1 Answers1

16

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
  • 178,213
  • 47
  • 333
  • 501
  • 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. – asfsadf Sep 23 '10 at 04:09
  • 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 Sep 23 '10 at 04:11
  • Interesting article. Thank you. – asfsadf Sep 23 '10 at 04:13
  • You mentioned that disposing the context is something you never do? Is my use of using() superfluous? – asfsadf Sep 23 '10 at 04:20
  • 1
    Aside from sorting and paging, `IQueryable` allows you to project onto presentation models without worrying about loading strategies. It "just works". – Craig Stuntz Sep 23 '10 at 13:20
  • 2
    I thought that if something implements `IQueryable` and you return it as `IEnumerable` the underlying object is still `IQueryable` and therefore retains delayed execution etc...? Hence the reason to return `IList`. – Charlino Sep 23 '10 at 17:22
  • @Charlino: `IQueryable` inherits from `IEnumerable`, so no, an `IEnumerable` is not an `IQueryable`. However, see my edit. – Robert Harvey Sep 23 '10 at 18:56
  • 1
    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 Sep 23 '10 at 19:38