>我正在尝试创建一个 ContainsAny 和 ContainsAll 扩展,所以我基本上可以执行以下操作
string[] words = keywords.split(' ');
from c in comments
where c.Text.ContainsAny(words)
select c
到目前为止,我已经设法做到了以下几点:
我有这两个扩展 and 和 or
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2) {
var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>(Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2) {
var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
}
然后我有:
Expression<Func<Entities.Comment, bool>> predicate = c => false;
foreach (string word in query.Split(' ')) {
string w = word;
predicate = predicate.Or(c => c.Text.Contains(w));
}
q = q.Where(predicate);
现在这一切都工作正常,但我不确定如何将此功能提取到一个通用扩展中,然后我可以对任何对象使用它。
任何帮助将不胜感激
public static IQueryable<T> ContainsAny<T>(this IQueryable<T> q, Expression<Func<T, string>> text, params string[] items)
{
Expression<Func<T, bool>> predicate = c => false;
var contains = typeof (String).GetMethod("Contains");
foreach (var item in items)
{
var containsExpression = Expression.Call(text.Body, contains, Expression.Constant(item, typeof (String)));
var lambda = Expression.Lambda<Func<T, bool>>(containsExpression, text.Parameters);
predicate = predicate.Or(lambda);
}
return q.Where(predicate);
}
现在你可以打电话
comments.ContainsAny(x => x.Text, words);
或
comments.ContainsAny(x => x.Text, "a", "b");
> 这个问题不是100%清楚的。在我看来,您正在尝试在 Linq 中实现一个通用的 ContainsAll/ContainsAny 谓词,您将在"where"子句中使用,所以我的实现是基于这个假设。
我会在IEmumerable上实现这些简单的扩展方法:
public static bool ContainsAny<T>(this IEnumerable<T> sequence, params T[] matches)
{
return matches.Any(value => sequence.Contains(value));
}
public static bool ContainsAll<T>(this IEnumerable<T> sequence, params T[] matches)
{
return matches.All(value => sequence.Contains(value));
}
这样你可以调用:
from c in comments
where (
c.Text.ContainsAny("A", "B") ||
c.Text.ContainsAll("X", "Y"))
select c
(即选择包含"A"或"B"的评论或(不完全包含)包含"X"和"Y"的评论)
//针对关键字集合实现包含全部
public static bool containsAll(this string description, string[] keywords) {
List<string> list = new List<string>();// new collection
string[] descriptionArray = description.Split(' ').Select(i => i).ToArray();
foreach (string s in keywords)
{ if (descriptionArray.Contains(s)) { list.Add(s);
} }
if (list.Count == keywords.Length) { return true; } return false;
}
包含任何 () 方法的实现
公共静态布尔值包含任何(此字符串描述,字符串[]关键字){
List<string> list = new List<string>();
string[] descriptionArray = description.Split(' ').Select(i => i).ToArray();
foreach (string s in keywords)
{ if (descriptionArray.Contains(s)) { list.Add(s); } }
if (list.Count == 0) { return true; } return false;
}