Search code examples
linqlistsearchlambdacontains

LINQ Lamba Select all from table where field contains all elements in list


I need a Linq statement that will select all from a table where a field contains all elements in a list<String> while searching other fields for the entire string regardless of words.

It's basically just a inclusive word search on a field where all words need to be in the record and string search on other fields.

Ie I have a lookup screen that allows the user to search AccountID or Detail for the entire search string, or search clientID for words inclusive words, I'll expand this to the detail field if I can figure out the ClientId component.

The complexity is that the AccountId and Detail are being searched as well which Basically stops me from doing the foreach in the second example due to the "ors".

Example 1, this gives me an the following error when I do query.Count() afterwards:

query.Count(); 'query.Count()' threw an exception of type 'System.NotSupportedException' int {System.NotSupportedException}

+base {"Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator."} System.SystemException {System.NotSupportedException}

var StrList = searchStr.Split(' ').ToList();

query = query.Where(p => p.AccountID.Contains(searchStr) || StrList.All(x => p.clientID.Contains(x)) || p.Detail.Contains(searchStr));

Example 2, this gives me an any search word type result:

var StrList = searchStr.Split(' ').ToList();
  foreach (var item in StrList)
    query = query.Where(p => p.AccountID.Contains(searchStr) || p.clientID.Contains(item) || p.Detail.Contains(searchStr));

Update

I have a table with 3 fields, AccountID, ClientId, Details

Records Id, AccountID, CLientId, Details

1, "123223", "bobo and co", "this client suxs"

2, "654355", "Jesses hair", "we like this client and stuff"

3, "456455", "Microsoft", "We love Mircosoft"

Search examples

searchStr = "232" Returns Record 1;

searchStr = "bobo hair" Returns no records

searchStr = "bobo and" Returns Record 1

searchStr = "123 bobo and" Returns returns nothing

The idea here is:

  • if the client enters a partial AccountId it returns stuff,
  • if the client wants to search for a ClientId they can type and cancel down clients by search terms, ie word list. due to the large number of clients the ClientID Will need to contain all words (in any order)

I know this seems strange but it's just a simple interface to find accounts in a powerful way.


Solution

  • I think there are 2 solutions to your problem.

    One is to count the results in memory like this:

    int count = query.ToList().Count();
    

    The other one is to not use All in your query:

    var query2 = query;
    foreach (var item in StrList)
    {
        query2 = query2.Where(p => p.clientID.Contains(item));
    }
    var result = query2.Union(query.Where(p => p.AccountID.Contains(searchStr) || p.Detail.Contains(searchStr)));
    

    The Union at the end acts like an OR between the 2 queries.