Like operator or using wildcards in LINQ to Entities

前端 未结 6 1336
抹茶落季
抹茶落季 2021-02-06 05:12

I\'m using LINQ 2 Entities. Following is the problem:

string str = \'%test%.doc%\' 
.Contains(str) // converts this into LIKE \'%~%test~%.doc~%%\'
6条回答
  •  生来不讨喜
    2021-02-06 05:40

    Following on from Magnus' correct answer, here is an extension method that can be re-used, as I needed in my project.

    public static class LinqExtensions
    {
        public static Expression> WildCardWhere(this Expression> source, Expression> selector, string terms, char separator)
        {
            if (terms == null || selector == null)
                return source;
    
            foreach (string term in terms.Split(new[] { separator }, StringSplitOptions.RemoveEmptyEntries))
            {
                string current = term;
                source = source.And(
                    Expression.Lambda>(
                        Expression.Call(selector.Body, "Contains", null, Expression.Constant(current)),
                        selector.Parameters[0]
                    )
                );
            }
    
            return source;
        }
    }
    

    Usage:

    var terms = "%test%.doc%";
    Expression> whereClause = d => d;
    whereClause = whereClause.WildCardWhere(d => d.docName, terms, '%');
    whereClause = whereClause.WildCardWhere(d => d.someOtherProperty, "another%string%of%terms", '%');
    var result = ListOfDocs.Where(whereClause).ToList();
    

    The extension makes use of the predicate builder at http://petemontgomery.wordpress.com/2011/02/10/a-universal-predicatebuilder/. The resulting sql does a single table scan of the table, no matter how many terms are in there. Jo Vdb has an example you could start from if you wanted an extension of iQueryable instead.

提交回复
热议问题