c# - 从 MethodCallExpression 获取投影

标签 c# .net linq expression-trees

我有一个带有 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;

最佳答案

不是很清楚你在做什么,但是

// 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)。请注意代码块开头的注释。

关于c# - 从 MethodCallExpression 获取投影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29721339/

相关文章:

c# - 托管 C++/CLI 方法中的可选参数

c# - 使用属性... INotifyPropertyChanged

c# - 将项目移动到数组中的第一个

c# - 如何使用 LINQ Contains(string[]) 而不是 Contains(string)

c# - 完成后重新打开表格一遍又一遍地计算时间

c# - foreach (where x => x.PROPERTY),如何设置PROPERTY?

c# - 有没有办法将 DateTimeOffset 转换为自午夜以来的分钟数?

c# - 最佳实践 : When should I use a delegate in . NET?

c# - 无法创建类型为 'xxx' 的常量值。在此上下文中仅支持原始类型或枚举类型

c# - Excel 对象模型中的 VBComponents 对象在哪里?