我一直在编写一段代码,允许您在要搜索的实体上定义许多属性。这很简单,但是当你开始使用诸如下面的表达式时,它就会失败:
this.HasColumn(e => e.FirstName + e.LastName, "FullName")
而不只是:
this.HasColumn(e => e.FirstName, "FirstName")
我有一个使用Expression.Call工作的表达式的模型,这是:
BinaryExpression memberExpression = Expression.MakeBinary(ExpressionType.Add, Expression.Property(pe, "FirstName"), Expression.Property(pe, "LastName"));
这是我的代码:
public IQueryable<T> Search(string valueToSearch, IQueryable<T> unfilteredList)
{
valueToSearch = valueToSearch.Replace(" ", "");
Expression<Func<T, bool>> expression = null;
foreach (var propertyName in this.Columns)
{
Expression<Func<T, bool>> lambda = null;
ParameterExpression parameterExpression = Expression.Parameter(typeof(T), "p");
Expression member = parameterExpression;
var canConvert = canConvertToType(valueToSearch, member.Type.FullName);
if (canConvert)
{
var value = convertToType(valueToSearch, member.Type.FullName);
if (IsString)
{
ParameterExpression pe = Expression.Parameter(typeof(T), "p");
var memberExpression = Expression.Add(Expression.Property(pe, "FirstName"), Expression.Property(pe, "LastName"), typeof(string).GetMethod("Concat", new[] { typeof(string), typeof(string) }));
Expression replaceMethodCall = Expression.Call(propertyName.Target, typeof(string).GetMethod("Replace", new[] { typeof(string), typeof(string) }), Expression.Constant(" ", typeof(string)), Expression.Constant("", typeof(string)));
MethodInfo methodInfo = typeof(string).GetMethod("Contains", new Type[] { typeof(string) });
ConstantExpression constantExpression = Expression.Constant(valueToSearch, typeof(string));
Expression call = Expression.Call(replaceMethodCall, methodInfo, constantExpression);
lambda = Expression.Lambda<Func<T, bool>>(call, pe);
}
else
{
lambda = Expression.Lambda<Func<T, bool>>(Expression.Equal(propertyName.Target.Body, Expression.Constant(value)), parameterExpression);
}
}
if (lambda != null)
{
if (expression == null)
{
expression = lambda;
}
else
{
expression = PredicateBuilder.Or(expression, lambda);
}
}
}
if (expression != null)
{
return unfilteredList.Where(expression);
}
// return an empty set
return new List<T>().AsQueryable();
}
我在哪里错了?为什么我只能使用我的Expression<Func<TEntity, string>>
作为其中的一部分?
编辑:这一行:
Expression replaceMethodCall = Expression.Call(propertyName.Target, typeof(string).GetMethod("Replace", new[] { typeof(string), typeof(string) }), Expression.Constant(" ", typeof(string)), Expression.Constant("", typeof(string)));
生成此异常:
Additional information: Method 'System.String Replace(System.String, System.String)' declared on type 'System.String' cannot be called with instance of type 'System.Func`2[GlobalSearchTest.Person,System.String]'