17

In my query i need to return IEnumerable but i dont know if this action make the query to execute again?

var data = Repository<Person>.Find().AsEnumerable();

Find() returns IQueryable and because IQueryable inherits IEnumerable. I doubt if AsEnumerable make the repetitive execution.

I know that var data = Repository<Person>.Find().ToList() executes the query two times. One for Find() and second for Tolist()

shashwat
  • 7,851
  • 9
  • 57
  • 90
Adrakadabra
  • 591
  • 2
  • 12
  • 23

3 Answers3

24

An IQueryable is an IEnumerable. There is no conversion, and therefore no work of any kind going on.

The work happens when you call GetEnumerator(), either explicitly or by invoking foreach on it.

Also, have you confirmed that Repository.Find().ToList() calls SQL twice? That doesn't sound right to me.

Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
  • 1
    To make this more correct. IQueryable is not an IEnumerable... but it does inherit from it. - http://stackoverflow.com/questions/2433306/whats-the-difference-between-iqueryable-and-ienumerable – Jimmyt1988 Sep 02 '16 at 13:43
13

AsEnumerable does not actually do anything except apply the as operator to your IQueryable. Accordingly, any future method you apply to your object will use the System.Linq.Enumerable set of extension methods as opposed to the System.Linq.Queryable methods.

It's all about deferred execution. Nothing ever gets executed against your queryable source (the database presumably) until you try to enumerate.

In other words:

var data=Repository.Find().AsEnumerable() 
/* The query is only actually performed AFTER here */  
.ToList();

If your code:

var data=Repository.Find().ToList();

executes the query two times, it's because you're doing something incorrect in your Find() method, which should definitely should not be the case.

var data = Respository.Find();

should execute the query ZERO times.

var result = data.ToList(); // THIS is what should execute the query.
Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632
Jeff
  • 35,755
  • 15
  • 108
  • 220
  • 1
    u were right i had tolist() at the end of find method and i didnt notice that.sry – Adrakadabra Oct 31 '10 at 05:49
  • You mentioned about how IQueryable inherits from IEnumerable and therefore the AsEnumerable will not warrant any run to the database. However, you also mentioned about how the subsequent methods on the object will be those on IEnumerable isntead of IQueryable. In this sense, does it mean once I run the IEnumerable method, the query will execute, come back and be queried in memory? Or does the rule that "only be executed on database if GetEnumerator() is called" still hold? – Andes Lam Aug 30 '21 at 06:20
2

think of linq as a "Stream" and aggregate function is a "Flush". "linq to db" stream can only flush once. .AsEnumerable(), .Where(), .... is a way to prepare query .ToList(), .First(), .Max() is an aggregate but if u not call aggregate, then your linq result wont run. its start to work only when its being enumerate.

ex

var result = users.Select(usr => usr.Name);

nothing will happen here until

1 aggregate is called

result.First()

or 2 result is being enumerate

result.ToList().ForEach(...)

to answer yout question - .Find(), .AsEnumerable() is not an aggregate function

Bonshington
  • 3,970
  • 2
  • 25
  • 20