我正在尝试搜索IQ的可识别集合的每个属性值与搜索查询的值。我有以下功能,想知道我如何一起测试NOT NULL和CONTAINS?
private Expression<Func<T, bool>> PropertySearch
{
get
{
// Object that is passed to the lambda expression
ParameterExpression instance = Expression.Parameter(typeof(T), "val");
Expression whereExpr = Expression.Constant(true); // default is val => True
var _properties = typeof(T).GetProperties();
foreach (var prop in _properties)
{
var query = _httpRequest["query"].ToLower();
var property = Expression.Property(instance, prop);
var toStringCall = Expression.Call(Expression.Call(
property,
"ToString",
new Type[0]),
typeof(string).GetMethod("ToLower", new Type[0]));
whereExpr = Expression.And(whereExpr,
Expression.Call(toStringCall, typeof(string).GetMethod("Contains"),
Expression.Constant(query)));
}
return Expression.Lambda<Func<T, bool>>(whereExpr, instance);
}}
答案 0 :(得分:0)
我创建了一个搜索扩展nuget包来执行此类检查。对于你的例子,我会做类似以下的事情。
注意,这是没有IDE的,因此可能会出现一些错误
/* *** Start: These can be made private reaonly fields ***/
var comparisonExpr = Expression.Constant(StringComparison.OrdinalIgnoreCase);
var zeroExpression = Expression.Constant(0)
var nullExpression = Expression.Constant(null)
MethodInfo IndexOfMethod = typeof(string).GetMethod("IndexOf", new[] { typeof(string), typeof(StringComparison) });
/* *** End ***/
Expression finalExpression = null
ParameterExpression instance = Expression.Parameter(typeof(T), "val");
var _properties = typeof(T).GetProperties();
var query = _httpRequest["query"].ToLower();
var queryExpr = Expression.Constant(query);
foreach (var prop in _properties)
{
//Get property
var propertyExpr = Expression.Property(instance, prop);
//Get property as string
var propStringExpr = Expression.Call(property, "ToString", new Type[0]);
//Perform IndexOf call
var indexOfExpr = Expression.Call(propStringExpr,
IndexOfMethod,
queryExpr,
comparisonExpr);
// Check index of is greater than or equal to zero
var containsExpr = Expression.GreaterThanOrEqual(containsExpr, zeroExpression);
if(finalExpression == null)
{
finalExpression = containsExp;
}
else
{
finalExpression = Expression.AndAlso(containsExpr);
}
}
return Expression.Lambda<Func<T, bool>>(finalExpression, instance);
我已删除ToLower()
的需要,而是使用IndexOf
字符串比较类型
如果您想了解我是如何实现类似功能的,请查看Github上的NinjaNye.SearchExtensions
如果您想搜索IQueryable
的集合,可以使用NinjaNye.SearchExtensions,如下所示
string query = _httpRequest["query"];
var result = data.SearchAll().Containing(query);
这将搜索所有字符串属性(不是您上面的所有属性),只返回任何属性与搜索字词匹配的字段。
希望这有帮助
答案 1 :(得分:0)
您可以使用PredicateBuilder,这样您就不必自己弄乱表达树了。