Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IEnumerable<T> and Take(x) issue?

(using Entity Framework)

when i write :

IEnumerable<string> q = customers /*EF entity*/
.Select (c => c.Name.ToUpper())
.OrderBy (n => n)

the c# compiler knows how to emit expression trees which in turn , the sql execute :

SELECT UPPER (Name) FROM Customer ORDER BY UPPER (Name)

notice also the order by clause is there

but

i saw this link :

he wrote :

IEnumerable<employee> emp = 
         dc.Employees.Where(x => x.Desc.StartsWith("soft"));
emp = emp.Take(1);

after investigating the final query he saw :

SELECT [t0].[Id], [t0].[Name], [t0].[Address], [t0].[Desc] AS [Desc]
FROM [dbo].[Employee] AS [t0]
WHERE [t0].[Desc] LIKE @p0

notice there is no top clause

why is that ?

shouldn't Take(x) be added to the query ?

will writing it like this :

IEnumerable<employee> emp = 
         (dc.Employees.Where(x => x.Desc.StartsWith("soft"))).Take(1);

would added the TOP clause to the query being sent to SQL ?

what is going here ?

( I already know that take is not a deferred execution)

like image 519
Royi Namir Avatar asked Dec 08 '22 23:12

Royi Namir


1 Answers

If you added Take(1) to the first expression, it would be on IQueryable<T>, and thus added to the SQL. But since you converted IQueryable<T> to IEnumerable<T>, Take(1) is done in memory: IEnumerable<T> has an identically-named Take() extension method, and as far as compiler knows, emp is IEnumerable<T>, not IQueryable<T>, so the in-memory version gets called.

like image 87
Sergey Kalinichenko Avatar answered Dec 11 '22 11:12

Sergey Kalinichenko