简体   繁体   中英

How to use Linq to check if a string contains one of a subset of strings

I have a case where a user is allowed to supply a set of keywords (more preceisely substrings) when searching for a user name.

I have something like

// this set of strings should find names such as john, mary or smith
List<string> searchStrings=new List<string>(){"jo","ma","th"}; 

// LINQ query looks like this

var filteredPatients=allPatients.Where(p =>
                            (searchStrings.Any(s=>p.Name.ToLower().Contains(s)));

However this fails and gives the exception:

System.AggregateException : One or more errors occurred. (The LINQ expression could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync()

This is running against entityFramework, .NET Core 3.1 against a Postgres Db

Is there another way to write this query to produce the desired result?

NOTE: it would be possible to call ToList() or ToArray() on allPaitents but I would like to avoid this as the whole (very large) table will be read into memory.

For starters you'll want a PredicateBuilder that will allow you to combine expressions together.

Using that, you can just create a predicate searching for each search string individually and then OR together those predicates.

List<string> searchStrings = new List<string>() { "jo", "ma", "th" };

var predicate = searchStrings.Select<string, Expression<Func<Patient, bool>>>(search => patient => patient.Name.ToLower().Contains(search))
    .DefaultIfEmpty(patient => false) //or whatever else you want to do if there are no search strings
    .Aggregate(PredicateBuilder.Or);
            
var filteredPatients = allPatients.Where(predicate);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM