当使用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)));
}
IQueryable的GetEnumerator
方法进行查询物化。