通用LINQ查询谓词?

时间:2020-03-06 14:38:32  来源:igfitidea点击:

不知道这是否可行,或者我是否正确表达了我要查找的内容,但是我的库中反复有以下代码,并且想练习一些DRY。
我有一组基于用户提供的简单搜索字段(例如Google)进行查询的SQL Server表。我正在使用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和Search的FieldName。这有意义吗? LINQ是否可以动态传递字段名称以在where子句中进行查询?还是可以将其作为谓词lambda传递?

e => e.FieldName.Contains(queryTerm)

我意识到有100万种方法可以用SQL进行此操作,这可能更容易,但是我很乐意将所有内容保留在LINQ系列中。另外,我觉得泛型对于这样的问题应该很方便。有任何想法吗?

解决方案

听起来像是我们基本上需要一个条件谓词构建器。

希望我们能将它塑造成我们想要的东西,祝我们好运!

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

听起来我们在寻找Dynamic Linq。在这里看看。这使我们可以将字符串作为参数传递给查询方法,例如:

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

编辑:使用C4的动态支持,有关此主题的另一组帖子:第1部分和第2部分。

我们可能想看一下表达式树:

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);

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