The following linq2entities code would appear to call the IEnumerable version of FirstOrDefault extension, because PersonHistories is an ICollection. At runtime however, it actually calls the IQueryable version.
var test = db.Persons.Where(d => d.PersonKey == 4) .Select(f => f.PersonHistories.FirstOrDefault());
The problem I am having is the custom query provider I am using does not perform this automatic conversion, and I get the error "...ICollection cannot be used for parameter of type IQueryable". Thus requires explicitly calling AsQueryable to work around this, but for complex queries it gets very redundant and not feeling very DRY:
db.Persons.Where(d => d.PersonKey == 4) .Select(f => f.PersonHistories.AsQueryable().FirstOrDefault());
I have dug around in the framework reference source trying to find the Linq 2 Entities visitors/provider stuff, but have had no luck(perhaps is not part of any of the open reference sources). How do the base providers accomplish this implicit use of AsQueryable?
I do understand that these are translated to expression trees. I do understand that the Enumerable.FirstOrDefault is replaced with Queryable.FirstOrDefault by the provider. That is the premise of the question.
How do the base providers accomplish this implicit use of AsQueryable?
They don't. Your code doesn't really execute FirstOrDefault() at all. It builds an expression tree which represents the call, but that isn't executed directly. The query provider sees that, works out that the f.PersonHistories is actually based on an entity which is in the database, and converts the query appropriately.