C# 根据搜索查询的值搜索T的IQueryable集合的每个属性值。如何测试notnull和CONTAINS?

C# 根据搜索查询的值搜索T的IQueryable集合的每个属性值。如何测试notnull和CONTAINS?,c#,linq,generics,expression-trees,iqueryable,C#,Linq,Generics,Expression Trees,Iqueryable,我正在尝试根据搜索查询的值搜索T的IQueryable集合的每个属性值。我有下面的函数,想知道如何同时测试NOTNULL和CONTAINS private Expression<Func<T, bool>> PropertySearch { get { // Object that is passed to the lambda expression ParameterExpression instance = Expression.Param

我正在尝试根据搜索查询的值搜索T的IQueryable集合的每个属性值。我有下面的函数,想知道如何同时测试NOTNULL和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);
}}

我已经创建了一个SearchExtensions nuget包来执行这种类型的检查。举个例子,我会做如下的事情

注意,这没有IDE,因此可能会有一些错误

这将搜索所有字符串属性,而不是像上面那样搜索所有属性,并返回与搜索词匹配的属性


希望这对您有所帮助

您可能会使用它,这样您就不必自己搞乱表达式树。

最简单的方法是对示例lambda进行硬编码,然后使用调试器查看它,以查看确切的子表达式是什么。在这种情况下,只需调用Expression.Equals。您已经完成了大部分工作。或者编译它并查看反汇编程序,例如ILSpy
/* *** 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);
string query = _httpRequest["query"];
var result = data.SearchAll().Containing(query);