通用LINQ查询谓词?
不确定这是否可行,或者我是否正确地表达了我正在寻找的内容,但我在我的库中反复使用以下代码,并希望练习一些DRY。 我根据用户提供的简单搜索字段ala Google查询了一组SQL Server表。 我正在使用LINQ根据搜索字符串中的内容组成最终查询。 我正在寻找一种方法来使用generics并传递lambda函数来创建一个可重用的例程:
string[] arrayOfQueryTerms = getsTheArray(); var somequery = from q in dataContext.MyTable select q; if (arrayOfQueryTerms.Length == 1) { somequery = somequery.Where( e => e.FieldName.StartsWith(arrayOfQueryTerms[0])); } else { foreach(string queryTerm in arrayOfQueryTerms) { if (!String.IsNullOrEmpty(queryTerm)) { somequery = somequery .Where( e => e.FieldName.Contains(queryTerm)); } } }
我希望创建一个带签名的generics方法,它看起来像:
private IQueryable getQuery( T MyTableEntity, string[] arrayOfQueryTerms, Func predicate)
我在所有表中使用相同的搜索策略,因此唯一与使用情况完全不同的是搜索到的MyTable和MyTableEntity以及搜索到的FieldName。 这有意义吗? 有没有办法让LINQ动态传入要在where子句中查询的字段名称? 或者我可以将其作为谓词lambda传入?
e => e.FieldName.Contains(queryTerm)
我意识到在SQL中有一百五十种方法可以做到这一点,可能更容易,但我很乐意将这一切保留在LINQ系列中。 此外,我觉得generics应该对这样的问题很方便。 有任何想法吗?
听起来你正在寻找Dynamic Linq。 看看这里 。 这允许您将字符串作为参数传递给查询方法,例如:
var query = dataSource.Where("CategoryID == 2 && UnitPrice > 3") .OrderBy("SupplierID");
编辑:关于此主题的另一组post,使用C#4的动态支持: 第1 部分和第2部分 。
您可能想要查看表达式树:
IQueryable getQuery (T myTableEntity, string[] arrayOfQueryTerms, Expression> predicate) { var fieldOrProperty = getMemberInfo(predicate); /* ... */ } MemberInfo getmemberInfo (Expression expr) { var memberExpr = expr as MemberExpression; if (memberExpr != null) return memberExpr.Member; throw new ArgumentException(); } var q = getQuery(foo, new[]{"Bar","Baz"}, x=>x.FieldName);
我最近不得不做同样的事情。 你需要Dynamic Linq 这是一种保持强类型的方法。