2

Lets assume, I have a IQuerable collection, and list of somestrings.

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 ?

  • 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
  • 104,599
  • 10
  • 205
  • 202
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
  • 666
  • 4
  • 14