我有一个select
的Linq查询,来自我的Linq查询提供程序,我得到一个包含MethodCallExpression
的表达式树,但我怎样才能获得选择来自MethodCallExpression
?
internal static object Execute(Expression expression, bool isEnumerable)
{
var whereExpression = expression as MethodCallExpression;
if (whereExpression == null) throw new InvalidProgramException("Error");
foreach (var arg in whereExpression.Arguments)
{
if (arg is UnaryExpression)
{
var unaryExpression = arg as UnaryExpression;
var lambdaExpression = unaryExpression.Operand as LambdaExpression;
if (lambdaExpression == null) continue;
// Here I would like to get the select projections, in this example the "word" projection ...
查询可能如下所示:
var queryable = new MyQueriableClass();
var query = from thing in queryable
where thing.id == 1
select word;
答案 0 :(得分:3)
目前还不清楚你在做什么,但是
// note the AsQueryable! Otherwise there is no
// Expression tree!
var words = new List<string>() { "an", "apple", "a", "day" }.AsQueryable();
// Note that even IQueryable<string> query = words;
// is a perfectly good query without a projection!
// The query
// from word in words where word.Length > 0 select word
// doesn't have a select too (try looking at the
// expression tree... The select has been elided)
// The projection if not present is implicit, the
// whole object.
var query = from word in words
select word;
var exp = query.Expression;
var methodCallExpression = exp as MethodCallExpression;
if (methodCallExpression != null)
{
MethodInfo method = methodCallExpression.Method;
if (method.DeclaringType == typeof(Queryable) && method.Name == "Select")
{
var source = methodCallExpression.Arguments[0];
var selector = methodCallExpression.Arguments[1];
// The selector parameter passed to Select is an
// Expression.Quote(subexpression),
// where subexpression is the lambda expression
// word => word here
if (selector.NodeType != ExpressionType.Quote)
{
throw new NotSupportedException();
}
UnaryExpression unary = (UnaryExpression)selector;
Expression operand = unary.Operand;
if (operand.NodeType != ExpressionType.Lambda)
{
throw new NotSupportedException();
}
LambdaExpression lambda = (LambdaExpression)operand;
// This is the "thing" that returns the result
Expression body = lambda.Body;
}
}
最后的body
应该是您想要的(或者在结束之前的lambda
)。请注意代码块开头的注释。