Как правило, SQL генерируется, когда GetEnumerator вызывается в IQueryable.
В вашем примере есть небольшая разница, которую вы можете рассмотреть. Давайте возьмем ваш оригинальный пример:
var query = db.Customers.Where (c => c.Age > 18);
query = query.Where (c => c.State == "CO");
var result = query.Select (c => c.Name);
В этом случае, если вы измените свой первый запрос на IEnumerable query = ..., тогда во второй строке будет использоваться версия IEnumerable расширения Where (LINQ to Objects), а не IQueryable (LINQ to SQL / EF) , В результате, когда мы начинаем итерацию, первое предложение where передается в базу данных, а второе предложение where выполняется на стороне клиента (поскольку оно уже преобразовано в IEnumerable).
Еще один тонкий элемент, о котором вы хотите знать, - это код следующего типа:
var query = db.OrderBy(c => c.State);
query = query.Customers.Where(c => c.Age > 18); // Fails: Widening
В этом случае, поскольку ваш исходный запрос возвращает IOrderedQueryable, а не IQueryable. Если вы попытаетесь назначить запрос результату операции .Where, вы попытаетесь расширить область действия возвращаемого типа, и компилятор откажется выполнить это расширение. В результате вы должны явно указать базовый тип, а не использовать var:
IQueryable<Customer> query = db.OrderBy(c => c.State); // Is narrowing rather than widening.
query = query.Customers.Where(c => c.Age > 18);