Frayt
Frayt

Reputation: 1223

LINQ - Where a string contains any element in an array

I have the following block of code:

string[] searchTerms = Request.QueryString["search"].Split(' ');
var searchResults = from i in Website.Images
                    join u in Website.Users on i.User_Id equals u.Id
                    where i.ImageTitle == searchTerms.Any()

searchTerms will contain multiple words, for example foo bar and baz. I want to check i.ImageTitle to see if it contains any of these words. So:

football will be returned

bar will be returned

bath will not be returned

I'm sure I have to use .Any and probably .Contains, but I'm not sure how to configure them.

Upvotes: 1

Views: 2799

Answers (1)

Erti-Chris Eelmaa
Erti-Chris Eelmaa

Reputation: 26268

The first thought is this:

var searchResults = from i in Website.Images
                    join u in Website.Users on i.User_Id equals u.Id
                    where searchTerms.Any(
                                term => i.imageTitle.Contains(term))
                    select i;

However, that is not quite correct, as you would be getting an error:

Exception information: Exception type: System.NotSupportedException Exception message: Local sequence cannot be used in LINQ to SQL implementation of query operators except the Contains() operator.

This happens because the searchTerms array can't be translated to SQL construction.

The usual work-around is to use PredicateBuilder to create a predicate from multiple search terms, and then use it in a final query:

var predicate = PredicateBuilder.False<YourImageType>();
foreach(string searchTerm in searchTerms)
   predicate = predicate.Or(image => 
                      image.imageTitle.Contains(searchTerm));

var searchResults = from i in Website.Images.Where(predicate)
                    join u in Website.Users on i.User_Id equals u.Id
                    select i;

Upvotes: 3

Related Questions