IEnumerable,IQueryable的区别
// 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)); }