用于针对标记化字符串构建 string.contains 动态 Linq 查询的通用函数
我使用 Expression.And
和 Expression.Or
来构建动态 linq 查询。当被查询的属性/字段是一个字符串,并且该字符串包含空格时,我想对空格上的字符串进行标记,并在标记上创建一个“And'd”子查询。
这就是我以非通用方式的意思,
var tokens = Code.Split(new []{" "}, StringSplitOptions.RemoveEmptyEntries);
var index = 0;
var firstToken = tokens[index ++];
Expression<Func<Entity, bool>> subQuery =
entity => entity.Code.Contains(firstToken);
for (; index < tokens.Length; index ++)
{
var tempToken = tokens[index];
subQuery = subQuery.And(entity => entity.Code.Contains(tempToken));
}
query = query.Or(subQuery);
我想做的是找到一种编写方法的方法,该方法足够通用,只需调用即可:
PredicateBuilder.BuildTokenizedStringQuery<Entity>(
tokens, entity => entity.Code);
并且我最终会得到相同的结果。以下是我所在的位置,但我无法在 Expression
中使用 Func
stringProp 访问器。我必须以某种方式将(字符串属性的)访问器表达式与调用表达式(调用 string.Contains
)结合起来,
private Expression<Func<T, bool>> BuildTokenizedStringQuery<T>(string[] tokens,
Func<T, string> stringProp)
{
var index = 0;
var firstToken = tokens[index++];
Expression<Func<T, bool>> subQuery = entity =>
stringProp(entity).Contains(firstToken);
for (; index < tokens.Length; index++)
{
var tempToken = tokens[index];
subQuery = subQuery.And(
entity => stringProp(entity).Contains(tempToken));
}
return subQuery;
}
我也有兴趣听听这是否是一个坏主意。
I am using Expression.And
and Expression.Or
to build dynamic linq queries. When the property/field being queried is a string, and the string contains spaces I would like to tokenize the string on the spaces and create an "And'd" sub query on the tokens.
Here is what I mean in a non generic fashion
var tokens = Code.Split(new []{" "}, StringSplitOptions.RemoveEmptyEntries);
var index = 0;
var firstToken = tokens[index ++];
Expression<Func<Entity, bool>> subQuery =
entity => entity.Code.Contains(firstToken);
for (; index < tokens.Length; index ++)
{
var tempToken = tokens[index];
subQuery = subQuery.And(entity => entity.Code.Contains(tempToken));
}
query = query.Or(subQuery);
What I'd like to do is find a way of writing a method which is generic enough to just call for example:
PredicateBuilder.BuildTokenizedStringQuery<Entity>(
tokens, entity => entity.Code);
and I end up with the same result. The following is where I'm at but I can't use the Func
stringProp accessor in and Expression
. I have to somehow combine an accessor expression (of the string property) with an invocation expression (that invokes string.Contains
)
private Expression<Func<T, bool>> BuildTokenizedStringQuery<T>(string[] tokens,
Func<T, string> stringProp)
{
var index = 0;
var firstToken = tokens[index++];
Expression<Func<T, bool>> subQuery = entity =>
stringProp(entity).Contains(firstToken);
for (; index < tokens.Length; index++)
{
var tempToken = tokens[index];
subQuery = subQuery.And(
entity => stringProp(entity).Contains(tempToken));
}
return subQuery;
}
I'd also be interested to hear if this all looks like a bad idea.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是我用来执行此操作的方法:
使用
结果
这将找到标题包含“kill”或“mockingbird”一词的所有书籍。
Here's what I use to do this:
Usage
Results
This will find all books whose title contains the words "kill" or "mockingbird."
乔什提供的答案非常棒,帮助我得到了我想要的东西。然而,它测试每个标记的相等性(它也更通用,因为可以针对任何类型测试相等性),而不是 string.Contains 测试。这是一个给出 string.Contains 结果的解决方案:
The answer Josh provided is awesome and helped me to get exactly what I want. It however tests for equality of each token (it is also more generic as equality can be tested against any type) as opposed to a string.Contains test. Here is a solution that gives a string.Contains result: