0

I want to build filters on IQueryable depending on user input and execute the query only at the end. I'm trying to understand concept behind and if this is going to work as expected.

Will the query below hit database on return fetchedWorkflowLogs.ToList() in the example below?

// Partition latest record for Instance
IQueryable<WorkflowLog> fetchedWorkflowLogs 
                                        = this._workflowLog_repo
                                            .GetAll()
                                            .GroupBy(log => log.ID)
                                            .Select(
                                                grp => new
                                                {
                                                    grp = grp,
                                                    MaxID = grp.Max(log => log.ID)
                                                }
                                            )
                                            .SelectMany(
                                                temp0 => temp0.grp,
                                                (temp0, log) => new
                                                {
                                                    temp0 = temp0,
                                                    log = log
                                                }
                                            )
                                            .Where(temp1 => (temp1.log.ID == temp1.temp0.MaxID))
                                            .Select(temp1 => temp1.log);

// .. some more filters                                         

// Last filter
// Filter by Project
if (model.ProjectID != null)
{
    fetchedWorkflowLogs.Where(record => record.Project.ID == model.ProjectID);
}

return fetchedWorkflowLogs.ToList();
skmasq
  • 4,470
  • 6
  • 42
  • 77
  • Well, that could depend on what `GetAll()` does. You can test this by stepping through in the debugger while profiling the database. But essentially, yes, things like `Select()` and `Where()` build up an expression tree which doesn't get evaluated until the collection is materialized with something like `ToList()`. – David Mar 23 '15 at 02:01
  • @David It does following `return _db.WorkflowLogs.AsQueryable();` – skmasq Mar 23 '15 at 02:01

1 Answers1

2

Agree with David. if GetAll() returns IQueryable, and you return fetchedWorkflowLogs.ToList() will result in the linq query being evaluated, and the query will hit database. It's the best if you can debug and step through, and writing a test could help you if execuing program directly is difficult.

Dongming Yan
  • 123
  • 9
  • Are there any methods that could execute prematurely the `IQueryable`? – skmasq Mar 23 '15 at 02:12
  • https://msdn.microsoft.com/en-us/library/vstudio/bb738633(v=vs.100).aspxAt what point query expressions are executed can vary. LINQ queries are always executed when the query variable is iterated over, not when the query variable is created. This is called deferred execution. You can also force a query to execute immediately, which is useful for caching query results. This is described later in this topic. – Dongming Yan Mar 23 '15 at 02:16
  • it includes: ToArray, ToList, ToDictionary, ForEach, ToLookup, Average, Count, First, and Max – Dongming Yan Mar 23 '15 at 02:19