Where in the call chain should Include() EF LINQ extension be positioned?
entity-framework, linq-to-entities
Solution
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).
Problem
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: - should Include be always first in the call chain? - does Count() get impacted by Include? If so I guess I should do Count after Include - should Include be before or after filtering (Where)? - does it really matter because EF is "smart" enough to figure out everything?