C# 通过Expression.Call调用Expression.GreaterThanOrEqual时发生ArgumentException

C# 通过Expression.Call调用Expression.GreaterThanOrEqual时发生ArgumentException,c#,entity-framework,reflection,lambda,expression-trees,C#,Entity Framework,Reflection,Lambda,Expression Trees,动态或直接调用Expression.GreaterThanOrEqual时,我会得到不同的行为 using System; using System.Linq.Expressions; using System.Reflection; namespace ExpressionExample { class Program { static void Main(string[] args) { // Build expres

动态或直接调用
Expression.GreaterThanOrEqual
时,我会得到不同的行为

using System;
using System.Linq.Expressions;
using System.Reflection;

namespace ExpressionExample
{
    class Program
    {
        static void Main(string[] args)
        {
            // Build expression head.
            ParameterExpression param = Expression.Parameter(typeof(MyObj), "x");
            MemberExpression property = Expression.Property(param, "MyProperty");

            int value = 1;

            // Build expression body.
            MethodInfo greaterThanOrEqual = typeof(Expression)
                .GetMethod("GreaterThanOrEqual",
                    new[] { typeof(Expression), typeof(Expression) });

            Expression valueExpr = Expression.Convert(Expression.Constant(value),
                property.Type);

            // Dynamic Call
            //var expressionBody = Expression.Call(null, greaterThanOrEqual, property,
                  valueExpr);
            // Direct Call
            var expressionBody = Expression.GreaterThanOrEqual(property, valueExpr);

            // Make Lambda.
            Expression.Lambda<Func<MyObj, bool>>(expressionBody, param);
        }
    }

    class MyObj
    {
        public int MyProperty { get; set; }
    }
}
使用系统;
使用System.Linq.Expressions;
运用系统反思;
名称空间表达式示例
{
班级计划
{
静态void Main(字符串[]参数)
{
//建立表达头。
ParameterExpression param=表达式参数(typeof(MyObj),“x”);
MemberExpression属性=Expression.property(参数“MyProperty”);
int值=1;
//构建表达式体。
MethodInfo greaterThanOrEqual=typeof(表达式)
.GetMethod(“GreaterThanOrEqual”,
新[]{typeof(表达式),typeof(表达式)});
表达式valueExpr=表达式.Convert(表达式.Constant(值),
属性(类型);
//动态呼叫
//var expressionBody=Expression.Call(null,greaterThanOrEqual,property,
valueExpr);
//直拨电话
var expressionBody=Expression.GreaterThanOrEqual(属性,valueExpr);
//做兰姆达。
表达式.Lambda(表达式体,参数);
}
}
MyObj类
{
公共int MyProperty{get;set;}
}
}
出于简单的原因,我将代码断章取义。后面的Lambda稍后在
Queryable
的where方法中使用。直接调用工作正常,并给出预期结果。但是,动态调用抛出一个
System.ArgumentException
,表示
System.Int32
不能用作
二进制表达式的参数。这就是我之前转换值的原因,这对于直接调用也是必要的


这里有什么区别?我怎样才能得到工作的动态呼叫?

我仍然不理解您的请求的实际用途(因此需要),所以只回答您的具体问题

这里有什么区别

不同之处在于
Expression.Call
并不真正调用该方法,而是创建了一个
MethodCallExpression
,它表示对表达式树内方法的调用。因此,它不应该用于调用其他
表达式
生成器方法

我怎样才能让动态电话投入工作

除了
Expression.Call
,您只需通过反射调用方法:

// Dynamic Call
var expressionBody = (Expression)greaterThanOrEqual.Invoke(
    null, new object[] { property, valueExpr });

区别在于,您所谓的动态调用根本不是调用。为了提供您是解决方案,您需要提供需要动态调用的示例用例。我用一个最小且可运行的示例更新了这个问题。好的,但这不是我需要的。我知道它是可复制的,但是为了回答您的第二个问题(如何使其工作),我找不到动态调用的实际需要(用例)。我正在处理一个由json控制的过滤器(表达式树)。因此,您向API发送请求以获取实体列表。响应包含的实体由(json)过滤器确定。过滤器是一个包含布尔代数的树形式的公式。目前,Equals表达式被分成各自的方法。现在我想给他们打电话,他们只有MethodInfo。