实体,包含或相交,这个查询是否可能
本文关键字:查询 是否 包含 实体 | 更新日期: 2023-09-27 18:09:33
我有一个字符串列表,通过这种方式检索:
List<string> keyWords = db.MotCleRecherche.Select(t => t.MotClé).ToList();
我还有一个需要执行许多参数的查询:
object = db.DAapp.Where(t => t.CODE_ART.StartsWith(s) && t.DATE_CREAT >= debut && t.DATE_CREAT < fin).ToList()
现在…我想添加这样的条件:
db.DAapp.Where(t => t.DESC_ART.ToLower().Contains(keywords.ToLower()))
或
db.DAapp.Where(t => t.DESC_ART.ToLower().Intersect(keywords.ToLower()))
我猜你能看到它的到来…我不知道该怎么做……我所知道的是考虑一个列表X归档和Y列表填充:
X.Intersect(Y).Any()
将返回true如果有相等的…但是DESC_ART只是一个长字符串,我想知道如果我的一些关键字在那里
我同意Stephen的观点,在比较之前应该先将keyWords强制转换为lower。但是如果你真的需要用linq来做这个,你可以这样做。
var result = db.DAapp.Where(t => keywords.Any(keyword=> string.Equals(keyword,t.DESC_ART, StringComparison.InvariantCultureIgnoreCase )));
这将导致在linq循环的每次迭代中对每个字符串调用a to,因此代价很高。
首先将此添加到您的项目中(例如添加到您的控制器中):
static Expression<Func<T, bool>> AnyOf<T>(
params Expression<Func<T, bool>>[] expressions)
{
if (expressions == null || expressions.Length == 0) return x => false;
if (expressions.Length == 1) return expressions[0];
var body = expressions[0].Body;
var param = expressions[0].Parameters.Single();
for (int i = 1; i < expressions.Length; i++)
{
var expr = expressions[i];
var swappedParam = new SwapVisitor(expr.Parameters.Single(), param)
.Visit(expr.Body);
body = Expression.OrElse(body, swappedParam);
}
return Expression.Lambda<Func<T, bool>>(body, param);
}
class SwapVisitor : ExpressionVisitor
{
private readonly Expression from, to;
public SwapVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node)
{
return node == from ? to : base.Visit(node);
}
}
我从stackoverflow中找到了这个。现在您可以创建所需的查询,如下所示:
var filters = new List<Expression<Func<Models.DAapp, bool>>>();
foreach (var st in keyWords)
filters.Add(d => d.DESC_ART.ToLower().Contains(st.ToLower()));
var lambda = AnyOf(filters.ToArray());
var q = db.DAapp.Where(t =>
t.CODE_ART.StartsWith(s)
&& t.DATE_CREAT >= debut
&& t.DATE_CREAT < fin
);
q = q.Where(lambda);
var res = q.ToList();
请注意,这个解决方案只创建一个包含多个where表达式的select查询。这是更有效的其他解决方案,如下面包含多个选择查询在where子句:
var q = db.DAapp.Where(t =>
t.CODE_ART.StartsWith(s)
&& t.DATE_CREAT >= debut
&& t.DATE_CREAT < fin
&& keyWords.Any(k => t.DESC_ART.ToLower().Contains(k.ToLower()))
);