Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which LINQ statements force Entity Framework to return from the DB?

I know of several LINQ statements that will cause EF to evaluate and return results form the DB to memory. .ToList() is one. Does anyone have a comprehensive list of the statements that do this?

Not sure of...

.SingleOrDefault()
.Union()

EDIT: Wish I could accept all these answers. Great info from everyone!

like image 727
jrizzo Avatar asked Jun 03 '15 15:06

jrizzo


People also ask

What does LINQ query return?

By default, LINQ queries return a list of objects as an anonymous type. You can also specify that a query return a list of a specific type by using the Select clause.

Which is correct about LINQ to Entities?

LINQ to Entities provides Language-Integrated Query (LINQ) support that enables developers to write queries against the Entity Framework conceptual model using Visual Basic or Visual C#. Queries against the Entity Framework are represented by command tree queries, which execute against the object context.

How does LINQ Entity Framework work?

Here, you will see an overview of how entity framework works. Entity Framework API (EF6 & EF Core) includes the ability to map domain (entity) classes to the database schema, translate & execute LINQ queries to SQL, track changes occurred on entities during their lifetime, and save changes to the database.

In which statement the LINQ query is executed?

This fact means it can be queried with LINQ. A query is executed in a foreach statement, and foreach requires IEnumerable or IEnumerable<T>. Types that support IEnumerable<T> or a derived interface such as the generic IQueryable<T> are called queryable types.


Video Answer


4 Answers

It's a long list. They boil down to

Aggregate
All<TSource>
Any
Average
Contains
Count
ElementAt<TSource>
ElementAtOrDefault<TSource>
Empty<TResult>
First
FirstOrDefault
Last
LastOrDefault
LongCount
Max
Min
SequenceEqual
Single
SingleOrDefault
Sum
ToArray<TSource>
ToDictionary
ToList<TSource>
ToLookup

The rest are either Deferred Streaming Execution or Deferred Non-Streaming Execution.

In light of your question, SingleOrDefault() is Immediate Execution and Union() is Deferred Streaming Execution.

like image 120
David L Avatar answered Nov 09 '22 02:11

David L


Anything that returns a concrete object or data structure (Count, Sum Single, First, ToList, ToArray, etc.) is evaluated immediately, so SingleOrDefault certainly does.

Anything that returns an IQueryable<T> (Select, GroupBy, Take) will be deferred (so that operations can be chained), so Queryable.Union will be deferred.

Anything that returns an IEnumerable<T> will also be deferred, but subsequent queries will be done in Linq-to-objects, so subsequent operations won't be translated to SQL. (Empty is an exception since there's not really anything to defer - it just returns an empty collection)

like image 41
D Stanley Avatar answered Nov 09 '22 02:11

D Stanley


From MSDN,

Queries that perform aggregation functions over a range of source elements must first iterate over those elements.

Examples of such queries are Count, Max, Average, and First. These execute without an explicit foreach statement because the query itself must use foreach in order to return a result.

Note also that these types of queries return a single value, not an IEnumerable collection.

To force immediate execution of any query and cache its results, you can call the ToList<TSource> or ToArray<TSource> methods.

like image 38
Rohit Vipin Mathews Avatar answered Nov 09 '22 03:11

Rohit Vipin Mathews


In the case of Entity Framework, there's an easy way to refresh your memory.

Entity Framework has Async variants of all such methods defined in System.Data.Entity, because Async doesn't make sense with the others as it's the very act of querying the database that the Async variants do asynchronously.

So if there's an Async variant, then it hits the database and otherwise it does not.

Enumerating or producing an IEnumerable<T> is a part-way case though: The act of obtaining an IEnumerable<T> obtaining its enumerator (as happens at the start of foreach blocks) does not hit the database, but the first MoveNext() (which happens immediately within the foreach does hit the database, and it then continues to stream from the resultset until either MoveNext() returns false (as when the foreach reaches a "natural" end) or the enumerator is disposed prior to that (as when the foreach is aborted).

like image 42
Jon Hanna Avatar answered Nov 09 '22 04:11

Jon Hanna