起因:就是一段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. The method getDispatcherType() is undefined for the type HttpServletRequest

    在使用百度的ueditor的时候,老是报错: The method getDispatcherType() is undefined for the type HttpServletRequest 原 ...

  2. JAVA基础篇NO2--Java中的基本命名规则及数据类型

    1.Java中的常量及进制 1.常量: 在程序运行的过程中,不可以改变的量,就是常量 boolean类型的值只能是true或者false null: 空常量, 代表不存在! ------------- ...

  3. C# 构造post参数一种看起来直观点的方法[转]

    因为本人经常爱用C#做一些爬虫类的小东西,每次构造post参数的时候,都是直接字符串拼接的方式的,有时候改起来不太方便. 场景: 需要post一个地址 参数列表 : username:管理员 pass ...

  4. How to install starDIct on suse OS?

    1. Access page http://code.google.com/p/stardict-3/ to download starDict package or use zypper in to ...

  5. AJAX的封装(包括跨域问题)

    注意: 1.同域下支持get和post方法 2.跨域问题必须得到后台的支持 3.跨域只支持get方法 function AJAX(obj){ //做网络请求的时候,参数以"对象"的 ...

  6. Python学习笔记 for windows

    学习来源 http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001374738136 ...

  7. java类初始化的过程

    在复习Thinking in java的过程中看到了相关内容,顺便整理一下,像下面一样的代码具体的执行顺序(ABCD都是类) public class A { public A(String text ...

  8. JAVASE02-Unit06: 文件操作——File 、 文件操作—— RandomAccessFile

    Unit06: 文件操作--File . 文件操作-- RandomAccessFile java.io.FileFile的每一个实例是用来表示文件系统中的一个文件或目录 package day06; ...

  9. C++学习笔记 宏 const 内联 枚举

    宏, const变量, 内联, 枚举 宏 宏定义: 宏即宏替换,在C语言源程序中允许用一个标识符来表示一个字符串,称为宏,关键字 define,在所有使用到宏的地方都只是直接的替换而不做任何类型检查 ...

  10. jira操作

    1. 字段 关键字 issuetype 2. 语法 2.1 in AND issuekey in (WQBNEWSDLDL-348, WQBNEWSDLDL-348, WQBNEWSDLDL-352, ...