通用 LINQ 查询谓词?
Posted
技术标签:
【中文标题】通用 LINQ 查询谓词?【英文标题】:Generic LINQ query predicate? 【发布时间】:2010-09-12 15:05:48 【问题描述】:不确定这是否可行,或者我是否正确表达了我正在寻找的内容,但我的库中反复有以下代码,并且想练习一些 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 家族中的所有内容。另外,我觉得泛型应该对这样的问题很方便。有什么想法吗?
【问题讨论】:
同样的问题,但对于 Select 子句:***.com/questions/10376947/… 【参考方案1】:听起来您正在寻找 Dynamic Linq。看看here。这允许您将字符串作为参数传递给查询方法,例如:
var query = dataSource.Where("CategoryID == 2 && UnitPrice > 3")
.OrderBy("SupplierID");
编辑:关于此主题的另一组帖子,使用 C# 4 的动态支持:Part 1 和 Part 2。
【讨论】:
谢谢!非常酷,我需要浏览 ScottGu 关于这个主题的所有博客文章...... 不幸的是,我只找到了一个 - 我以为他有一个系列,但我想我错了。不过还有其他信息来源。 很抱歉在这里提出一个问题。什么是谓词,它与 linq 有什么关系? 谓词是一个计算结果为布尔值的表达式。谓词用作 LINQ 表达式中 Where 子句的参数。在上面的示例中,CategoryID == 2 && UnitPrice > 3
是一个谓词。
我认为 Gridify 是一个更好的选择。 github.com/alirezanet/Gridify【参考方案2】:
听起来你基本上想要一个条件谓词构建器..
我希望你能把它塑造成你正在寻找的东西,祝你好运!
http://www.albahari.com/nutshell/predicatebuilder.aspx
【讨论】:
【参考方案3】:您可能想查看表达式树:
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 答案是我将要使用的答案,但谢谢你,我明天也会尝试解决这个问题。【参考方案4】:我最近不得不做同样的事情。您将需要 Dynamic Linq here 是一种保持这种强类型化的方法。
【讨论】:
【参考方案5】:我建议尝试 Gridify 库。 它更容易使用,性能也更好。
用法示例:
query = dataSource.ApplyFiltering("FiledName=John");
这是动态 LINQ 库之间的性能比较。
【讨论】:
以上是关于通用 LINQ 查询谓词?的主要内容,如果未能解决你的问题,请参考以下文章
linq查询中不同级别导航属性的相同where条件的通用表达式函数