设为首页 加入收藏

TOP

【C#夯实】我与接口二三事:IEnumerable、IQueryable 与 LINQ(三)
2019-09-17 18:23:52 】 浏览:74
Tags:夯实 我与 接口 二三 IEnumerable IQueryable LINQ
> throw new NotImplementedException(); public IQueryProvider Provider => throw new NotImplementedException(); public IEnumerator GetEnumerator() { throw new NotImplementedException(); } }

 

  IQueryable是IEnumerable的孩子(IQueryable : IEnumerable),它是一个有自己花样的迭代器。这个花样如何体现呢?关键还在于Expression、IQueryProvider上。

  从字面上来看,Expression是查询条件的表达式树;那么Provider就是提供数据的成员了。

    public class QueryableSample : IQueryable
    {
        public Expression Expression { get; }
        public Type ElementType => typeof(ModelItem);
        public IQueryProvider Provider { get; }

        public IEnumerator GetEnumerator()
        {
            return Provider.Execute<IEnumerable>(Expression).GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public QueryableSample(IQueryProvider provider, Expression expression)
        {
            if (provider == null)
                throw new ArgumentNullException("provider");
            if (expression == null)
                throw new ArgumentNullException("expression");

            Provider = provider;
            Expression = expression;
        }
    }
View Code

  预感中,Provider会是个重要角色:

public class QueryProvider : IQueryProvider

IQueryable CreateQuery(Expression expression)

return new QueryableSample(this, expression);

IQueryable<TElement> CreateQuery<TElement>(Expression expression)

return (IQueryable<TElement>) new QueryableSample(this, expression);

object Execute(Expression expression)

return QueryResult.Execute(expression, false);

TResult Execute<TResult>(Expression expression)

bool IsEnumerable = (typeof(TResult).Name == "IEnumerable`1");

return (TResult)QueryResult.Execute(expression, IsEnumerable);

 

    public class QueryProvider : IQueryProvider
    {
        public IQueryable CreateQuery(Expression expression)
        {
            return new QueryableSample(this, expression);
        }
        public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
        {
            return (IQueryable<TElement>) new QueryableSample(this, expression);
        }
        public object Execute(Expression expression)
        {
            return QueryResult.Execute(expression, false);
        }
        public TResult Execute<TResult>(Expression expression)
        {
            bool IsEnumerable = (typeof(TResult).Name == "IEnumerable`1");
            return (TResult)QueryResult.Execute(expression, IsEnumerable);
        }
    }
    public sealed class QueryResult
    {
        public static object Execute(Expression expression, bool isEnumerable)
        { // 利用expression得到数据结果,设其为records
            QueryableSample records = null;
            if (isEnumerable)
                return records.Provider.CreateQuery(expression);
            else
                return records.Provider.Execute(expression);
        }
    }
View Code

 

  在github上找到了个详尽些的QueryableDemo可以看: https://github.com/andreychizhov/NestQueryableProvider

 

三、IEnumerable 与 IQueryable

   下面以一个例子比较二者最大的区别[2]:

            var q = from c in dbContext.Customers

                       where c.City == "London"

                       select c;

            var finalAnswer = fro

首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇ASP.NET+d3.js实现Sqlserver数据.. 下一篇新增筛选方案

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目