zoukankan      html  css  js  c++  java
  • 原来Queryable是这样实现的..

    一直没去细想为什么Enumerable和Queryable提供了两套签名一致的方法.今天在扩展IQToolkit,使之支持Insert/Update/Delete的过程中,遇到了问题,用Reflector看了一下Queryable类的源码,顿时醍醐灌顶.

    在给代表数据库表格的类EntityTable(实现了IQueryable<TEntity>接口)添加一个扩展方法Delete(Expression<Predicate<TEntity>>)来做生成Delete语句的标识时,发现这个方法被直接调用了,觉得很郁闷.明明微软自己的Where, Select等方法都没被调用,而是作为Expression给传到了QueryProvider里, 凭什么我自己写的方法你就不给翻译一下传过去,而是当场执行呢?

    不对啊,First, Single之类的方法也是当场执行的啊,难道编译器会根据方法的返回类型(是不是相同的IQueryable<T>)来决定如何对待它们?或者,可能有某个应用于方法上的Attribute,可以控制编译器这方面的行为?

    还是看看Queryable里的代码是怎么写的吧.打开Reflector一看Queryable.First方法,马上明白了:

    public static TSource First<TSource>(this IQueryable<TSource> source)
    {
        if (source == null)
        {
            throw Error.ArgumentNull("source");
        }
        return source.Provider.Execute<TSource>(Expression.Call(null, ((MethodInfo) MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[] { typeof(TSource) }), new Expression[] { source.Expression }));
    }

    晕了,原来根本不是编译器在捣鬼!这方法纯粹是一混蛋,屁事不干的主.不单屁事不干,还指使别人说,你再来调用我吧..

    再看Queryable.Where:

    public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate)
    {
        if (source == null)
        {
            throw Error.ArgumentNull("source");
        }
        if (predicate == null)
        {
            throw Error.ArgumentNull("predicate");
        }
        return source.Provider.CreateQuery<TSource>(Expression.Call(null, ((MethodInfo) MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[] { typeof(TSource) }), new Expression[] { source.Expression, Expression.Quote(predicate) }));
    }

    First和Where的区别在于两者调用了不同的方法,一个要求直接执行对应的动作,一个要求返回一个新的IQueryable<T>对象以推迟实际行为的发生.

    哎,这世界上怎么那么多比我聪明的人呢?

  • 相关阅读:
    silverlight的Datagrid控件列绑定属性笔记
    VC字符串处理整理
    Combobox实现多项选择 Silverlight下“Combobox”怎样实现多项选择?
    C# 类初始化顺序
    Silverlight程序设置断点无法进入调试的解决方案
    有哪些适合新手练手的Python项目?
    Ubuntu 终端常用命令
    浅析python 中__name__ = '__main__' 的作用
    py thon 多线程(转一篇好文章)
    python os.path模块
  • 原文地址:https://www.cnblogs.com/deerchao/p/1379684.html
Copyright © 2011-2022 走看看