实体,包含或相交,这个查询是否可能

本文关键字:查询 是否 包含 实体 | 更新日期: 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()))
                           );