使用 PredicateBuilder 跨 Entity 的多列构建查询搜索
Using PredicateBuilder to build query searching across multiple columns of Entity
我有一个字段名称列表。我正在尝试构建一个谓词来查看字段以查看它们是否包含搜索词。我已经完成了此 original question 中列出的路径,但不明白如何使用 Contains 而不是 NotEqual.
string searchTerm = "Fred";
foreach (var field in FieldNames)
{
myPredicate= myPredicate.And(m => m.*field*.Contains(searchTerm));
}
到目前为止我的代码:
public static Expression<Func<T, bool>> MultiColumnSearchExpression<T>(string fieldName,string searchValue)
{
var parameter = Expression.Parameter(typeof(T), "m");
var fieldAccess = Expression.PropertyOrField(parameter, fieldName);
//this next line should do a Contains rather then NotEqual but how?
var body = Expression.NotEqual(fieldAccess, nullValue);
var expr = Expression.Lambda<Func<T, bool>>(body, parameter);
return expr;
}
Expression.NotEqual
是二元运算符!=
。由于您的 Contains
调用不是二元运算符,因此无法直接替代它。
相反,您需要做的是 Contains
的方法调用。因此,您首先需要为 string.Contains
函数获取 MethodInfo
对象。
它应该是这样的:
var method = typeof(string).GetMethod("Contains");
var body = Expression.Call(fieldAccess, method, Expression.Constant(searchValue));
所以你想调用 String.Contains
方法。
这是一个String
class 实例方法,具有以下签名
public bool Contains(string value)
可以映射到以下Expression.Call
overload:
public static MethodCallExpression Call(
Expression instance,
string methodName,
Type[] typeArguments,
params Expression[] arguments
)
方法如下:
public static Expression<Func<T, bool>> ContainsPredicate<T>(string memberName, string searchValue)
{
var parameter = Expression.Parameter(typeof(T), "m");
var member = Expression.PropertyOrField(parameter, memberName);
var body = Expression.Call(
member,
"Contains",
Type.EmptyTypes, // no generic type arguments
Expression.Constant(searchValue)
);
return Expression.Lambda<Func<T, bool>>(body, parameter);
}
我有一个字段名称列表。我正在尝试构建一个谓词来查看字段以查看它们是否包含搜索词。我已经完成了此 original question 中列出的路径,但不明白如何使用 Contains 而不是 NotEqual.
string searchTerm = "Fred";
foreach (var field in FieldNames)
{
myPredicate= myPredicate.And(m => m.*field*.Contains(searchTerm));
}
到目前为止我的代码:
public static Expression<Func<T, bool>> MultiColumnSearchExpression<T>(string fieldName,string searchValue)
{
var parameter = Expression.Parameter(typeof(T), "m");
var fieldAccess = Expression.PropertyOrField(parameter, fieldName);
//this next line should do a Contains rather then NotEqual but how?
var body = Expression.NotEqual(fieldAccess, nullValue);
var expr = Expression.Lambda<Func<T, bool>>(body, parameter);
return expr;
}
Expression.NotEqual
是二元运算符!=
。由于您的 Contains
调用不是二元运算符,因此无法直接替代它。
相反,您需要做的是 Contains
的方法调用。因此,您首先需要为 string.Contains
函数获取 MethodInfo
对象。
它应该是这样的:
var method = typeof(string).GetMethod("Contains");
var body = Expression.Call(fieldAccess, method, Expression.Constant(searchValue));
所以你想调用 String.Contains
方法。
这是一个String
class 实例方法,具有以下签名
public bool Contains(string value)
可以映射到以下Expression.Call
overload:
public static MethodCallExpression Call(
Expression instance,
string methodName,
Type[] typeArguments,
params Expression[] arguments
)
方法如下:
public static Expression<Func<T, bool>> ContainsPredicate<T>(string memberName, string searchValue)
{
var parameter = Expression.Parameter(typeof(T), "m");
var member = Expression.PropertyOrField(parameter, memberName);
var body = Expression.Call(
member,
"Contains",
Type.EmptyTypes, // no generic type arguments
Expression.Constant(searchValue)
);
return Expression.Lambda<Func<T, bool>>(body, parameter);
}