0

I am a beginner to use linq and i have a problem with this code when i use IEnumerable it return data but with IQueryable it doesn't and i don't know why ,, and another question how when using IEnumerable it return data without using functions like ToList().

 public IQueryable<TempDTO> GetAllWorkers()
        {
            var query = (from q in _context.X
                         select new TempDTO
                         {
                             id=q.id,
                             .
                             .
                             .

                             Machines = GetMachinesListById(q.Id)
                         });
            return query;
        }
        private IEnumerable<Temp2DTO> GetMachinesListById(int? id){ // return query with machines}
        


And this is my api

public IActionResult GetAllWorkers()
        {
            var result = _Repo.GetAllWorkers().Where(// condition);
            return Ok(result);
        }

Thanks in advance.

Ahmed Mohamed
  • 231
  • 4
  • 15
  • 1
    I think this post does a pretty good job of explaining the difference between the two interfaces and also how to use them effectively. https://stackoverflow.com/questions/2876616/returning-ienumerablet-vs-iqueryablet – A-A-ron Jun 24 '20 at 01:23
  • 1
    *when i use IEnumerable* -- Where/how exactly? Please post the exact code that does work and the code that doesn't. – Gert Arnold Jun 24 '20 at 09:26
  • The `return query with machines` code is the code we need to see to be able to answer your question properly. – Enigmativity Jun 24 '20 at 11:04

2 Answers2

1

I think @A-A-ron has given you an explanation in the comment.

Because you use the custom method GetMachinesListById in linq, if you use IQueryable, the GetMachinesListById method will not be recognized on the sql side, so an exception will occur.

It is precisely because of their differences that when you use IEnumerable, all current objects will be executed on the current client, so the GetMachinesListById method can be recognized and executed.

Have a look for Client vs. Server Evaluation.

If you want to use IQueryable, you need to add .ToList() to _context.X.

 public IQueryable<TempDTO> GetAllWorkers()
        {
            var query = (from q in _context.X.ToList()
                         select new TempDTO
                         {
                             id=q.id,
                             .
                             .
                             .

                             Machines = GetMachinesListById(q.Id)
                         });
            return query;
        }

and another question how when using IEnumerable it return data without using functions like ToList().

For this question, IEnumerable and ToList are two different types. If you want to display the style of ToList, then you can only add the ToList method after Where as follow:

var result = _Repo.GetAllWorkers().Where(condition).ToList();
LouraQ
  • 6,443
  • 2
  • 6
  • 16
0

My understanding is that IQueryable is more or less a reference to the query itself, and until the query is run (for example, by calling .ToList() or .ToArray()), it won't be populated by data.

In your case, you could ensure your IQueryable is executed within your API controller method by calling '.ToList()':

var result = _Repo.GetAllWorkers().Where(condition).ToList();
return Ok(result);
Chris Brenberg
  • 142
  • 1
  • 6
  • Thanks for ur answer but how when i use IEnumerable it working and return data without using ToList() ? – Ahmed Mohamed Jun 23 '20 at 15:43
  • 1
    IEnumerable executes the 'SELECT' immediately and stores the results in memory, and the filtering (in your .Where()) is done on the client. IQueryable does the filtering on the server by adding a WHERE clause to the query before executing. – Chris Brenberg Jun 23 '20 at 15:49
  • 1
    This article shows the actual SQL that is generated by each. https://www.c-sharpcorner.com/UploadFile/a20beb/ienumerable-vs-iqueryable-in-linq/ – Chris Brenberg Jun 23 '20 at 15:50
  • 1
    @ChrisBrenberg - No. `IEnumerable` uses lazy evaluation the same as `IQueryable`. It does not execute immediately. Both are executed when you iterate the collections, i.e. use `.ToList()`. – Enigmativity Jun 24 '20 at 09:05
  • @ChrisBrenberg - That article is terrible with many misleading and plain wrong statements. – Enigmativity Jun 24 '20 at 09:08