java lambda orderby_关于Linq中的Lambda表达式中OrderBy的深入理解

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

IQueryable slist = (from s in EFDB.Student select s).

OrderBy(i => i.Name).Skip(( - ) * ).Take();

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

直接上源码吧

[__DynamicallyInvokable]

public static IOrderedQueryable OrderBy(this IQueryable source, Expression> keySelector)

{

if (source == null)

{

throw Error.ArgumentNull("source");

}

if (keySelector == null)

{

throw Error.ArgumentNull("keySelector");

}

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

}

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

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

[__DynamicallyInvokable]

IQueryable CreateQuery(Expression expression);

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

.method public hidebysig newslot abstract virtual instance class System.Linq.IQueryable` CreateQuery(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) arguments);

}

再进一步看Call

[__DynamicallyInvokable]

public static MethodCallExpression Call(Expression instance, MethodInfo method, IEnumerable arguments)

{

ContractUtils.RequiresNotNull(method, "method");

ReadOnlyCollection onlys = arguments.ToReadOnly();

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 args) : base(method)

{

this._arguments = args;

}

看到这里,我们就可以反推回去,Call方法最后就是把arguments(IEnumerable集合)返回给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 OrderBy(this IQueryable source, Expression> keySelector)

可以理解为

public static IOrderedQueryable OrderBy(LambdaExpression )

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

(from s in EFDB.Student select s)

.OrderBy(i => i.Name)

.Skip(( - ) * )

.Take();

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

dcec7b89ddb0e9bd127e65021fcd3b73.png

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

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

3dc3dbe0d02c33a29830f314e77b7243.png

完毕!

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

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

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

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

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

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

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

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

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

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

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

C++11中的Lambda表达式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值