ステートメントがToList()で実行されると、生成された基になる SQL は Id == id ステートメントを考慮し、フィルター項目のみを返します。
簡単な答えは「はい」です。
対応するものはEnumerable.ToList<T>(this IEnumumerable<T> e)
ありませんIQueryable<T>
GetMyClasses
メソッド内のすべてが として動作しますIQueryable<T>
が、後で追加された制限はインメモリになります。
IEnumerable<MyClass> GetMyClasses(int id) {
return GetQuery().Where(p => p.Id==id); // this always will work as IQueryable and handled by provider (in case of EF - the DB query will be performed)
}
IEnumerable<MyClass> MoreRestrictions(int id) {
return GetMyClasses(id)
.ToList(); // result list will be filtered by Id
}
IEnumerable<MyClass> MoreRestrictions(int id) {
return GetMyClasses(id)
.Where(x=>x.IsActive) // this where will be performed in memory on results filtered by Id.
.ToList();
}
メソッドToList
とWhere
は、次のように動作します
//There is only one implementation of ToList()
public List<T> ToList<T>(this IEnumerable<T> e)
{
var list = new List<T>();
var enumerator = e.GetEnumerator();
while (enumerator.MoveNext())
{
var item = e.Current;
list.Add(item);
}
return list;
}
//Implementation for IEnumerable
public IEnumerable<T> Where<T>(this IEnumerable<T> e, Predicate predicate)
{
var enumerator = e.GetEnumerator();
while (enumerator.MoveNext())
{
var item = e.Current;
if (predicate(item))
yield return item;
}
}
//Implementation for IQueryable
public IQueryable<T> Where<T>(this IQueryable<T> e, Expression<Predicate> predicate)
{
MethodBase method = ...; // create generic method of Queryable.Where()
return e.Provider
.CreateQuery<T>(Expression.Call(null, method, e.Expression, Expression.Quote(predicate)));
}
GetEnumerator
IQueryableのメソッドは、クエリの実体化を行います。