I noticed that Linq in .net core 2.0 returns IEnumerable, instead of the usual IQueryable, you can work with EF, but if there are 2 million records in the database and they are loaded into memory, it will be bad. In the solution only found connect: System.Linq.Queryable . But this does not help, since I have not found a way to mow the old Linq.

enter image description here

  • one
    What method does IEnumerable return from instead of IQueryable? - Andrey NOP
  • one
    Give your code. - Dmitry Polyanin
  • one
    What do you mean by "mowing the old Linq"? - Pavel Mayorov
  • @PavelMayorov did not say so, sorry, delete the link to System.Linq.Enumerable - Alexey
  • one
    @ Alexey is enough to add System.Linq.Queryable. Delete why? - Pavel Mayorov

2 answers 2

There is no full method code, so the answer is at random:

IQueryable<TEntity> = dbSet.Where(predicate); 

Most likely the predicate declared as

 Func<TEntity, bool> predicate = ... 

The fact is that the Queryable.Where method accepts not Func<TEntity, bool> , but Expression<Func<TEntity, bool>> .

But the Enumerable.Where method takes just Func<TEntity, bool> .

Func<TEntity, bool> is just a delegate that takes a TEntity and returns a bool . Inside the delegate, there can be any method with a suitable signature.

If you write

 Func<TEntity, bool> predicate = e => e.Id > 5; 

the compiler will simply create a view method

 bool someMethod(TEntity e) { return e.Id > 5; } 

You can call this delegate, but you can climb inside the delegate, get the contents of the method from there and somehow turn it into SQL. Therefore, a delegate is sufficient for Enumerable , but not for Queryable .


Expression<Func<TEntity, bool>> is an object, not a method.

If you write in code

 Expression<Func<TEntity, bool>> predicate = e => e.Id > 5; 

then the compiler will deploy it around

 Expression<Func<TEntity, bool>> predicate = Expression.Lambda( Expression.MakeBinary( ExpressionType.Equal, Expression.PropertyAccess("e", "Id"), Expresison.Const("5").... 

and now the LINQ provider can easily parse such a tree of objects and turn it into the corresponding SQL code.


Usually in the code for working with LINQ use lambdas. Lambdas are compiled either into anonymous methods or into expression trees, depending on the context. In this case, the expression tree is considered the preferred option. Those. if you write

 dbSet.Where(e => e.Id == 5); 

then the compiler will prefer overloading with Expression and, accordingly, the IQueryable mechanism. But since you explicitly set the predicate type to Func - you forcibly chose an IEnumerable .

Change the type of predicate to Expression<> and everything will be ok.

    If you use filtering by Where, it will be executed on the server side, and nothing extra will be unloaded.

     using (var context = new BloggingContext()) { var blogs = context.Blogs .Where(b => b.Url.Contains("dotnet")) .ToList(); } 

    This code will generate SQL with the condition WHERE blogs.Url LIKE '% dotnet%' and execute it on the database side at the time of listing the array. In the above code, this will happen at the time of the call .ToList ();

    Read the documentation

    • Yes, but it will work if you call Queryable.Where , not Enumerable.Where . The localization of queries in the repository is based on this feature - to return IEnumerable, and then the external code will not be able to build queries that are incompatible with the database. - PashaPash
    • @PashaPash DbSet<>.Where should IQueryable return - Dmitry Polyanin
    • 2
      @DmitryPolyanin, but all the same that he returns. Where is the extension method. IQueryable inherits from IEnumerable, if the compiler does not see the System.Linq.Queryable class, but see System.Linq.Enumerable, then the static method System.Linq.Enumerable.Where will be called, which will create WhereEnumerableIterator and reevaluate everything in memory. - PashaPash
    • @PashaPash did not know such subtleties, but it means that in this case the compiler does not see IQueryable ... - Dmitry Polyanin
    • four
      @DmitryPolyanin in the usual .net and System.Linq.Queryable and System.Linq.Enumerable are in System.Core, i.e. or they both are, or they are both not. The compiler prefers methods from System.Linq.Queryable. in them, the parameters of the beam correspond to the call. In .net core System.Linq.Queryable lies in System.Linq.Queryable.dll, if you disable it, the compiler will see only methods from System.Linq.Enumerable, lambdas will be compiled into anonymous methods, and not into expression trees, and Where will work on side of c #. - PashaPash