// List的繼承關系 public class List<T> : IList<T>, ICollection<T>, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable {
public List();public List(int capacity); public List(IEnumerable<T> collection); public T this[int index] { get; set; } ****** public Enumerator GetEnumerator(); }
//IQueryable的繼承關系
public interface IQueryable : IEnumerable { Type ElementType { get; } Expression Expression { get; } IQueryProvider Provider { get; } }
using System.Linq.Expressions; namespace System.Linq { public interface IQueryProvider { IQueryable CreateQuery(Expression expression); IQueryable<TElement> CreateQuery<TElement>(Expression expression); object Execute(Expression expression); TResult Execute<TResult>(Expression expression); } }
// IEnumerable接口
public interface IEnumerable { IEnumerator GetEnumerator(); }
總結:
1. IQueryable, List 繼承自 IEnumerator, 就是說這兩個都可以進行集合的遍歷。
2. IQueryable有三個屬性用戶存儲數據的類型,查詢的表達式和和Provider(數據的提供者,例如LINQ to SQL、Oracle EF Data Provider等)
當我們使用IQueryable進行Linq查詢時使用的IQueryable在linq里的擴展方法,如下代碼所示,
public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, int, bool>> predicate) { if (source == null) { throw System.Linq.Error.ArgumentNull("source"); } if (predicate == null) { throw System.Linq.Error.ArgumentNull("predicate"); } Expression[] arguments = new Expression[] { source.Expression, Expression.Quote(predicate) }; return source.Provider.CreateQuery<TSource>(Expression.Call(null, GetMethodInfo<IQueryable<TSource>, Expression<Func<TSource, int, bool>>, IQueryable<TSource>>(new Func<IQueryable<TSource>, Expression<Func<TSource, int, bool>>, IQueryable<TSource>>(Queryable.Where<TSource>), source, predicate), arguments)); }
就是說它返回的仍然是IQueryable對象,如 IQueryable.Where().Join().Groupby().Count().在where時沒有真正執行查詢,而是把查詢條件expression保存起來,繼續向下走,join()同理,Groupby同理,直到count時才執行真正的查詢,,如下所示:
public static int Count<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate) { if (source == null) { throw System.Linq.Error.ArgumentNull("source"); } if (predicate == null) { throw System.Linq.Error.ArgumentNull("predicate"); } Expression[] arguments = new Expression[] { source.Expression, Expression.Quote(predicate) };
// 這里執行真正的查詢 return source.Provider.Execute<int>(Expression.Call(null, GetMethodInfo<IQueryable<TSource>, Expression<Func<TSource, bool>>, int>(new Func<IQueryable<TSource>, Expression<Func<TSource, bool>>, int>(Queryable.Count<TSource>), source, predicate), arguments)); }