2

Let's assume I have an IQueryable collection, and list of some strings.

I can build query this way:

foreach (var somestring in somestrings)
{
     collection = collection.Where(col=>col.Property.Contains(somestring);
}

which will produce following SQL query:

SELECT ...... FROM ..... WHERE 
(Property LIKE '%something1%') AND 
(Property LIKE '%something2%') AND 
(Property LIKE '%something3%')

Note, that WHERE clauses are connected with ANDs.

Is there way, to construct similar query, but connected with ORs ?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 1
    The performance of that query would be very bad, whether you use `AND` or `OR`. Instead of using LINQ you should consider using full text search queries and indexes. The current query will scan the entire table to find matches without any benefit from indexes – Panagiotis Kanavos May 28 '19 at 08:18

2 Answers2

3

You can do this in one query without looping using Any:

var result = collection
    .Where(col => somestrings
        .Any(s => col.Property.Contains(s)));

Or the same query with simplified syntax:

var result = collection
    .Where(col => somestrings
        .Any(col.Property.Contains));
DavidG
  • 113,891
  • 12
  • 217
  • 223
1

You can use a PredicateBuilder like this. See SO for more.

Here you can connect queries with AND or OR.

IQueryable<Product> SearchProducts (params string[] keywords)
{
  var predicate = PredicateBuilder.False<Product>();

  foreach (string keyword in keywords)
  {
    string temp = keyword;
    predicate = predicate.Or (p => p.Description.Contains (temp));
  }
  return dataContext.Products.Where (predicate);
}

Sample taken from C# 7.0 in a Nutshell

I've used this successfully when implementing custom search fields

eg.

[red blue] -> searches for red AND blue

[red, blue] -> searches for red OR blue

Vanice
  • 676
  • 5
  • 15