LINQ 表达式树 - 参数 'x' 未绑定到指定的 LINQ to Entities 查询表达式中
LINQ Expression Tree - The parameter 'x' was not bound in the specified LINQ to Entities query expression
我正在尝试动态构建表达式树以从数据库中获取数据。
以下代码用于此。
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()
时,我得到一个异常
The parameter 'x' was not bound in the specified LINQ to Entities
query expression.
用于创建表达式的方法:
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;
}
构建此类表达式时,您必须保留顶级参数表达式实例。当您在 GetBinaryOperation
函数中创建一个新的参数表达式时,这将是一个 不同的实例 (因此 未绑定 术语),不管它的名字是否相同 "x"
.
您应该将原始 LambdaExpression
的 "x"
参数传递给 GetBinaryOperation
函数,而不是创建新的参数实例,例如使用 expression.Parameters[0]
.
总而言之,在这种情况下,您必须在整个表达式树中使用 same parameter expression instance
。
我正在尝试动态构建表达式树以从数据库中获取数据。
以下代码用于此。
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()
时,我得到一个异常
The parameter 'x' was not bound in the specified LINQ to Entities query expression.
用于创建表达式的方法:
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;
}
构建此类表达式时,您必须保留顶级参数表达式实例。当您在 GetBinaryOperation
函数中创建一个新的参数表达式时,这将是一个 不同的实例 (因此 未绑定 术语),不管它的名字是否相同 "x"
.
您应该将原始 LambdaExpression
的 "x"
参数传递给 GetBinaryOperation
函数,而不是创建新的参数实例,例如使用 expression.Parameters[0]
.
总而言之,在这种情况下,您必须在整个表达式树中使用 same parameter expression instance
。