起因:就是一段Linq语句,OrderBy里面的i是什么? 

 IQueryable<Student> slist = (from s in EFDB.Student select s).
OrderBy(i => i.Name).Skip(( - ) * ).Take();

说来也奇怪,同样是形参s就能理解,就是数据集合。 那OrderBy里面的i是什么?

直接上源码吧

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

这里是一个扩展方法,扩展的是 IQueryable<TSource> 类,

这个方法关键看最后一句话,返回一个CreateQuery方法,看一下它的源码

[__DynamicallyInvokable]
IQueryable<TElement> CreateQuery<TElement>(Expression expression);

IL代码(这个参考,不用在意)

.method public hidebysig newslot abstract virtual instance class System.Linq.IQueryable`<!!TElement> CreateQuery<TElement>(class System.Linq.Expressions.Expression expression) cil managed
{
.custom instance void __DynamicallyInvokableAttribute::.ctor()
}

那么下面这个就相当于CreateQuery方法的Expression 参数

Expression.Call(null, ((MethodInfo) MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[] { typeof(TSource), typeof(TKey) }), new Expression[] { source.Expression, Expression.Quote(keySelector) })

那么再进一步看看Call方法,这个方法就是返回的Expression 参数

[__DynamicallyInvokable]
public static MethodCallExpression Call(Expression instance, MethodInfo method, params Expression[] arguments)
{
return Call(instance, method, (IEnumerable<Expression>) arguments);
}

再进一步看Call

[__DynamicallyInvokable]
public static MethodCallExpression Call(Expression instance, MethodInfo method, IEnumerable<Expression> arguments)
{
ContractUtils.RequiresNotNull(method, "method");
ReadOnlyCollection<Expression> onlys = arguments.ToReadOnly<Expression>();
ValidateMethodInfo(method);
ValidateStaticOrInstanceMethod(instance, method);
ValidateArgumentTypes(method, ExpressionType.Call, ref onlys);
if (instance == null) //现在instance就是等于null
{
return new MethodCallExpressionN(method, onlys);
}
return new InstanceMethodCallExpressionN(method, instance, onlys);
}

继续看MethodCallExpressionN方法

public MethodCallExpressionN(MethodInfo method, IList<Expression> args) : base(method)
{
this._arguments = args;
}

看到这里,我们就可以反推回去,Call方法最后就是把arguments(IEnumerable<Expression>集合)返回给CreateQuery,而这个arguments形参就是CreateQuery的

new Expression[] { source.Expression, Expression.Quote(keySelector) }

再看看这里的Quote方法

[__DynamicallyInvokable]
public static UnaryExpression Quote(Expression expression)
{
RequiresCanRead(expression, "expression");
if (!(expression is LambdaExpression)) //如果不是lambda表达式,则抛异常
{
throw Error.QuotedExpressionMustBeLambda();
}
return new UnaryExpression(ExpressionType.Quote, expression, expression.GetType(), null); //
}

看到这里,终于知道原来

public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)

可以理解为

public static IOrderedQueryable<TSource> OrderBy(LambdaExpression )

至此,终于明白开头这句话的

 (from s in EFDB.Student select s)
.OrderBy(i => i.Name)
.Skip(( - ) * )
.Take();

OrderBy里面的i是取决于之前是谁调用的这个方法

上面source代表实体集,source.Expression代表实体集中的每一个实体。=> 也就是说lambda表达式中的形参i,代表一个实体,而不是实体集。

个人推测,Linq中OrderBy、Where都是返回的按照各自method、筛选器之后的集合,泛型委托。这种写法有点像链式编程。

完毕!

如有不正确的地方,请不吝赐教。

感谢我的几位好友:时同学、邵同学、倪同学、黄同学等对我一直以来的帮助。

因为我们都知道一个道理:单则易折、众则难摧。

     

关于Linq中的Lambda表达式中OrderBy的深入理解的更多相关文章

  1. 在Linq to sql 和 Entity framework 中使用lambda表达式实现left join

    在Linq to sql 和 Entity framework 中使用lambda表达式实现left join 我们知道lambda表达式在Linq to sql 和 Entity framework ...

  2. C#中的Lambda表达式和表达式树

    在C# 2.0中,通过方法组转换和匿名方法,使委托的实现得到了极大的简化.但是,匿名方法仍然有些臃肿,而且当代码中充满了匿名方法的时候,可读性可能就会受到影响.C# 3.0中出现的Lambda表达式在 ...

  3. 编写高质量代码改善C#程序的157个建议——建议27:在查询中使用Lambda表达式

    建议27:在查询中使用Lambda表达式 LINQ实际上是基于扩展方法和Lambda表达式的.任何LINQ查询都能通过扩展方法的方式来代替. var personWithCompanyList = f ...

  4. 你知道C#中的Lambda表达式的演化过程吗

    你知道C#中的Lambda表达式的演化过程吗? 阅读目录 委托的使用 匿名方法 Func和Action Lambda的诞生 那得从很久很久以前说起了,记得那个时候... 懵懂的记得从前有个叫委托的东西 ...

  5. C++11中的Lambda表达式

    原文地址:C++中的Lambda表达式 作者:果冻想 一直都在提醒自己,我是搞C++的:但是当C++11出来这么长时间了,我却没有跟着队伍走,发现很对不起自己的身份,也还好,发现自己也有段时间没有写C ...

  6. Qt5中使用lambda表达式

    c11新特性中加入了lambda表达式,所以Qt 也支持 需在.pro文件中加入 CONFIG += c++11 例子: QString program = "C:/Windows/Syst ...

  7. Java语言与JVM中的Lambda表达式全解

    Lambda表达式是自Java SE 5引入泛型以来最重大的Java语言新特性,本文是2012年度最后一期Java Magazine中的一篇文章,它介绍了Lamdba的设计初衷,应用场景与基本语法. ...

  8. Lambda 表达式中的变量范围

    delegate bool D(); delegate bool D2(int i); class Test { D del; D2 del2; public void TestMethod(int ...

  9. Lambda 表达式,Java中应用Lambda 表达式

    一.Lambda 表达式 简单来说,编程中提到的 lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数. 链接:知乎 先举一个普通的 Python 例 ...

随机推荐

  1. CACHE COHERENCE AND THE MESI PROTOCOL

    COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION In contemporary multi ...

  2. 3D滚动下拉菜单-简直不要太任性

    预览 先看看最终效果 简介 由来 最初看到这个是在14年5月,猛戳这里:妙味官网,觉得非常炫.想要做出来,所以就开始学习web. 那时候是做c/s的,也因为这个走上了b/s之路,(゚Д゚≡゚Д゚) 现 ...

  3. C# LINQ

    Sorting: OrderBy ThenBy OrderByDescending ThenByDescending Reverse public IEnumerable<Customer> ...

  4. JDK1.8导致发送邮件失败

    问题:本地JDK1.6测试可以发送邮件,但是linux上jdk1.8发送邮件失败.报错: Sending the email to the following server failed : smtp ...

  5. Python开发【前端】:DOM

    DOM(文档对象模型(Document Object Model)) 文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标志语言的标准编程接口.在网页 ...

  6. mysql用户密码修改,用户添加、删除及设置权限

    一下的示例所用用户名和密码为:test,111111 Mysql密码修改: Mysql修改密码需要root的权限,先执行mysql -uroot -p(密码); 1)使用set password方式来 ...

  7. JSTL 自定义标签

    编写描述标签的tld文件,把这个文件放到web-inf/目录下,才能在jsp页面上调用自定义的标签 package test.yz; import java.io.IOException; impor ...

  8. System.Web.AspNetHostingPermission 类型的权限已失败

    System.Security.SecurityException: 请求“System.Web.AspNetHostingPermission, System, Version=2.0.0.0, C ...

  9. cookie和session简单的用法

    一.登录成功则设置cookie和session 二.在登录页判断是否已记住密码 三.在首页判断,和创建会话区 四.在首页执行并显示

  10. JAVA-JNI java程序调用c/c++程序

    目的:写c/c++函数,让java调用 java代码 1.创建HelloJNI.java文件->编写代码如下->cmd中javac HelloJNI.java获取HelloJNI.clas ...