原来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>对象以推迟实际行为的发生.
哎,这世界上怎么那么多比我聪明的人呢?
原来Queryable是这样实现的..相关推荐
- MongoDB 开源“可查询加密”系统 Queryable Encryption
整理 | 彭慧中 责编 | 屠敏 出品 | CSDN(ID:CSDNnews) 多年来,数据泄露与黑客攻击令人苦不堪言.全世界都急于寻找一种工具来阻止个人敏感数据的非法流动,然而一个关键性的进展已经初 ...
- Linq中的Enumerable和Queryable
前言 正文 使用场合不同 返回类型不同 传递参数不同 总结 前言 此文章延续自C#中Linq的使用 正文 上节讲到Linq可以通过查询方法来使用,Linq中有两个命名空间,分别是System.Linq ...
- 开源:ASP.NET MVC+EF6+Bootstrap开发框架
前言 我在博客园潜水两三年了,在这里看过很多大神的文章,也学到了很多东西.可以说我是汲取着博客园的营养成长的. 想当年,我也是拿10个G的精神粮食从一个博客园大神那里换来一套开发框架,正式走上开发之路 ...
- MVC+Ninject+三层架构+代码生成 -- 总结(四、數據層)
1.數據層使用了SqlSugar 庫類 . 數據層使用了SqlSugar 庫類 ,有興趣的 可以學習 http://www.codeisbug.com/Doc/8/1133,個人覺得比EF 簡單,容 ...
- graphql_普通英语GraphQL指南
graphql by Luis Aguilar 路易斯·阿吉拉尔(Luis Aguilar) 普通英语GraphQL指南 (A Guide to GraphQL in Plain English) 您 ...
- 耗时3天,上亿数据如何做到秒级查询?
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源:sohu.gg/jIp59N 最近在忙着优化集团公司的一个报 ...
- 教你如何实现c#文件上传下载功能
简单介绍一下c#文件上传下载功能实现. NuGet 安装SqlSugar Model文件下新建 DbContext 类 public class DbContext {public DbContext ...
- java 拉姆表达式_强大的拉姆表达式转Sql 类库 - SqlSugar 隐藏功能之Lambda
使用场景 1.Lambda to sql 一直是ORM中最难的功能之一,如果有现成的解析库那么自已写一个ORM难度将大大降低 2.通过Lambda作为KEY进行缓存操作,特别是仓储模式想要拿到表达式进 ...
- mysql java orm_ObjectiveSQL(Java ORM) 之 MySQL 实战
第一步,引用Maven依赖: com.github.braisdom objective-sql 1.3.4 第二步,使用Annotation 定义一个DomainModel : import com ...
最新文章
- 精准广告系统架构调研
- 周志华:“数据、算法、算力”,人工智能三要素在未来还要加上“知识”
- python降级-关于卸载:如何从Python 3.2降级到2.7?
- 20165214 预备作业3 Linux安装及学习
- 华为鸿蒙宣传悟空视频_给华为“鸿蒙”打Call,家居头条号探讨短片《悟空》获50万阅读...
- php 伪造微信浏览器头信息,php使用curl伪造浏览器访问操作示例
- C++_limits头文件
- Java基于SSM的宠物店管理系统
- react中使用video标签显示本地视频不生效问题
- 谷歌浏览器安装 elasticsearch-head 插件
- Beyond Compare4破解方法
- 程序员编程规范之注释
- 连连跨境支付独立站收款,最高90天提现0费率!
- 二手平台android界面,Android二手书交易app设计(2)启动图Activity
- [重要笔记]路由器的包转发操作(全面认识路由器)
- 思科三层交换机开启ipv6路由功能_思科路由器配置 IPv6 和 OSPFv3 路由
- 机器学习笔记马尔可夫链蒙特卡洛方法(二)马尔可夫链与平稳分布
- 各种文件对应的文件类型
- 云数据库 Redis 版
- java做全选反选功能_[Java教程]js实现全选反选
热门文章
- c++调用python找不到py文件的可能原因
- 我心中的核心组件(可插拔的AOP)~第十五回 我的日志组件Logger.Core(策略,模版方法,工厂,单例等模式的使用)...
- Apache Storm源码阅读笔记
- [一文一命令]ln命令详解
- 设计模式 (一) 初次体验
- 深度剖析WinPcap之(二)——网络分析与嗅探的基础知识(4)
- 【译】TetroGL: An OpenGL Game Tutorial in C++ for Win32 Platforms - Part 2 (上)
- ZooKeeper 特点有哪些?
- 浅谈长连接的平滑重启
- 天猫精灵 python_python爬天猫