19

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

e => e.FieldName.Contains(queryTerm)

我意识到在 SQL 中有一百万种方法可以做到这一点,可能更容易,但我很乐意为这个保留 LINQ 家族中的所有内容。另外,我觉得泛型应该对这样的问题很方便。有任何想法吗?

4

5 回答 5

15

听起来您正在寻找 Dynamic Linq。看看这里。这允许您将字符串作为参数传递给查询方法,例如:

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

编辑:关于这个主题的另一组帖子,使用 C# 4 的动态支持:第 1部分和第 2 部分

于 2008-09-24T04:29:11.123 回答
7

听起来你基本上想要一个条件谓词构建器..

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

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

于 2008-09-24T04:25:59.603 回答
6

您可能想查看表达式树:

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);
于 2008-09-24T04:32:46.730 回答
0

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

于 2008-11-08T21:16:58.320 回答
0

我建议尝试使用Gridify库。它更容易使用,也有更好的性能。

用法示例:

query = dataSource.ApplyFiltering("FiledName=John");

这是动态 LINQ 库之间的性能比较。 在此处输入图像描述

于 2021-09-18T13:00:48.873 回答