Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where in the call chain should Include() EF LINQ extension be positioned?

I am curious where in the call chain should include be called when using Entity Framework. Consider following method:

// sample usage from service layer
// _customerRepository.Paginate(1, out totalRecords, 25, "DateJoined DESC, AmountSpent", "DateJoined >= '2009-02-01'", "Invoices, Refunds");
public virtual IQueryable<T> Paginate(int page, out int total, int pageSize, string sort = "Id", string filter = null, string includes = null)
{
    IQueryable<T> query = DatabaseSet;

    total = query.Count(); // get total # of records (required for pagination)...
    var skipTo = GetValidSkipCount(page, total, pageSize);

    if (!String.IsNullOrWhiteSpace(filter))
    {
        query.Where(filter);
    }
    // should includes be before filtering? 
    // should query.Count() be called after query.Include? 
    // does it matter?
    if (!String.IsNullOrWhiteSpace(includes))
    {
        query.IncludeMany(includes); // my own extension that takes comma separated string of entities to include
    }

    return query.OrderBy(sort).Skip(skipTo).Take(pageSize);
}

My questions are:

  1. should Include be always first in the call chain?
  2. does Count() get impacted by Include? If so I guess I should do Count after Include
  3. should Include be before or after filtering (Where)?
  4. does it really matter because EF is "smart" enough to figure out everything?
like image 795
zam6ak Avatar asked Jun 05 '12 15:06

zam6ak


People also ask

What is include in Entityframework?

Entity Framework Classic Include The Include method lets you add related entities to the query result. In EF Classic, the Include method no longer returns an IQueryable but instead an IncludeDbQuery that allows you to chain multiple related objects to the query result by using the AlsoInclude and ThenInclude methods.


1 Answers

should Include be always first in the call chain?

Include doesn't have to be the first in the chain. Include is very special operator which is not part of the query. It is like expansion of the query. It is also not LINQ operator - it is EF operator defined on ObjectQuery<T> (IQueryable<T> extension and DbQuery<T> version both internally get to this implementation). The T defines the shape of the query and the root for Include. Include is used only if the resulting shape of the query match root used in Include call. So if you add Include to call on IQueryable<T> and your query returns IQueryable<T> your Include is applied but if your query returns for example IQueryable of anonymous type you changed the shape of the query and Include is not applied.

does Count() get impacted by Include? If so I guess I should do Count after Include

Include is not used if you execute Count on the query. Count executes query and it doesn't return data record set - it changes the shape and there is nothing to include.

should Include be before or after filtering (Where)?

It should not matter. Include creates join and I expect both EF (when building the query) and query engine in database (when executing the query) should use filtering prior to applying join.

does it really matter because EF is "smart" enough to figure out everything?

It matters only if you change the shape of the query - you use projection or custom join. In such case Include of former shape will be lost (not used at all).

like image 137
Ladislav Mrnka Avatar answered Oct 03 '22 01:10

Ladislav Mrnka