代码之家  ›  专栏  ›  技术社区  ›  Codewerks

通用LINQ查询谓词?

  •  18
  • Codewerks  · 技术社区  · 16 年前

    不确定这是否可行,或者我是否正确地表达了我要寻找的内容,但是我在我的库中反复地使用了下面的代码,并且希望练习一些枯燥的代码。 我有一组SQL Server表,它们是基于一个简单的用户提供的搜索字段ala google进行查询的。我正在使用LINQ根据搜索字符串中的内容编写最终查询。我正在寻找一种使用泛型的方法,并传入lambda函数,以此创建一个可重用的例程:

    string[] arrayOfQueryTerms = getsTheArray();
    
    var somequery = from q in dataContext.MyTable
                    select q;
    
    if (arrayOfQueryTerms.Length == 1)
    {
        somequery = somequery.Where<MyTableEntity>(
            e => e.FieldName.StartsWith(arrayOfQueryTerms[0]));
    }
    else
    {
        foreach(string queryTerm in arrayOfQueryTerms)
        {
            if (!String.IsNullOrEmpty(queryTerm))
            {
                somequery = somequery 
                            .Where<MyTableEntity>(
                                e => e.FieldName.Contains(queryTerm));
            }
        }
    }
    

    我希望创建一个带有签名的通用方法,它看起来像:

    private IQueryable<T> getQuery(
        T MyTableEntity, string[] arrayOfQueryTerms, Func<T, bool> predicate)
    

    我在所有表中都使用相同的搜索策略,因此,不同用法之间唯一真正不同的是搜索的MyTable&MyTableEntity和搜索的FieldName。这有道理吗?LINQ是否可以在WHERE子句中动态传递要查询的字段的名称?或者我可以把它作为谓词lambda传递吗?

    e => e.FieldName.Contains(queryTerm)
    

    我意识到在SQL中有很多种方法可以做到这一点,可能更简单,但我很想保留Linq家族中的所有东西。另外,我觉得对于这样的问题,仿制药应该是很方便的。有什么想法吗?

    4 回复  |  直到 10 年前
        1
  •  15
  •   Devraj Gadhavi    10 年前

    听起来你在找动态LINQ。看一看 here . 这允许您将字符串作为参数传递给查询方法,例如:

    var query = dataSource.Where("CategoryID == 2 && UnitPrice > 3")
                          .OrderBy("SupplierID");
    

    编辑:关于这个主题的另一组文章,使用C 4的动态支持: Part 1 Part 2 .

        2
  •  7
  •   Quintin Robinson    16 年前

    听起来像是基本上需要一个条件谓词生成器。

    我希望你能把它做成你要找的东西,祝你好运!

    http://www.albahari.com/nutshell/predicatebuilder.aspx

        3
  •  6
  •   IAbstract    13 年前

    您可能需要查看表达式树:

    IQueryable<T> getQuery<T>(T myTableEntity, string[] arrayOfQueryTerms, Expression<Func<T, bool>> predicate)
     { var fieldOrProperty = getMemberInfo(predicate);
       /* ... */
     }
    
    MemberInfo getmemberInfo<T>(Expression<Func<T,bool> expr)
     { var memberExpr = expr as MemberExpression;
       if (memberExpr != null) return memberExpr.Member;
       throw new ArgumentException();
     }
    
    var q = getQuery<FooTable>(foo, new[]{"Bar","Baz"}, x=>x.FieldName);
    
        4
  •  0
  •   user17060    16 年前

    我最近不得不做同样的事情。你需要 Dynamic Linq here 是保持此强类型的一种方法。