实体,包含或交叉,这个查询可能吗?

时间:2016-09-28 20:38:19

标签: c# entity-framework

我有一个以这种方式检索的字符串列表:

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只是一个长字符串,我想知道我的某些关键字是否在那里

2 个答案:

答案 0 :(得分:1)

我同意斯蒂芬的观点,你应该在比较之前首先将关键词降低。但如果你真的需要用linq做这件事,你可以做这样的事情。

var result =  db.DAapp.Where(t => keywords.Any(keyword=> string.Equals(keyword,t.DESC_ART, StringComparison.InvariantCultureIgnoreCase )));

这将导致在你的linq循环的每次迭代中为每个字符串调用降低,因此它很昂贵。

答案 1 :(得分:-1)

首先将其添加到您的项目中(例如添加到您的控制器):

      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表达式的选择查询。这比其他解决方案更有效,如下面的where子句包含多个select查询:

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()))
                           );