LINQ表达式树-在指定的LINQ to Entities查询表达式中未绑定参数“ x”

时间:2018-12-15 16:50:10

标签: c# entity-framework linq expression-trees

我试图动态构建一个表达式树,以从数据库中获取数据。

以下代码用于此目的。

Expression<Func<Client, bool>> expression = x => true;
foreach (var item in searchParams)
{
    var operatorType = ExpressionType.Equal;
    string propertyName = null;
    object value = null;
    string keyValue = item.Value;

    if (item.Key == Constants.SearchParameterNames.Id)
    {
        int val = 0;
        if (int.TryParse(keyValue, out val))
            value = val;
        propertyName = "ClientID";
    }
    else if (item.Key == Constants.SearchParameterNames.Lastupdate)
    {
        DateTime dateTime;
        if (DateTime.TryParse(keyValue, out dateTime))
            value = dateTime;
        propertyName = "LastChange";
    }

    if (!string.IsNullOrWhiteSpace(propertyName) && value != null)
    {

            var exp = GetBinaryOperation<Client>(propertyName, operatorType, value);
            var exp1 = Expression.And(expression.Body, exp);
            expression = Expression.Lambda<Func<Client, bool>>(exp1, expression.Parameters);
    }

}
var client = _clientRepository.FindBy(expression).ToList();

执行_clientRepository.FindBy(expression).ToList()时,我得到了一个例外

  

参数“ x”未在指定的LINQ中绑定到实体   查询表达式。

用于创建表达式的方法:

public BinaryExpression GetBinaryOperation<T>(string propertyName, ExpressionType type, object value)
{

    var parameterExpression = Expression.Parameter(typeof(T), "x");
    var memberExpression = Expression.Property(parameterExpression, propertyName); 
    var propertyType = GetMemberType(memberExpression);
    var rhs = Expression.Constant(value);
    var binaryExpression = Expression.MakeBinary(type, memberExpression, rhs);

    return binaryExpression; 
}

1 个答案:

答案 0 :(得分:2)

构建这样的表达式时,您必须保留顶级参数表达式实例。当您在GetBinaryOperation函数中创建新的参数表达式时,它将是一个不同的实例(因此, not bound 术语),无论其名称是相同的"x"

您应该使用例如LambdaExpression将原始"x"的{​​{1}}参数传递给GetBinaryOperation函数,而不是创建新的参数实例。

总而言之,在这种情况下,您必须在整个表达式树中使用expression.Parameters[0]