Manmohan Manmohan - 1 month ago 4
C# Question

MVC ASP.Net LINQ syntax to search for any or part of string

I'm attempting to search in a column for ANY of the words in the search string(space de-limited).
I'm able to search for whole string (using .Contains) but not ANY of the words it is made of.


eg: search_field = {apples, pears, bananas, grapes}

search_string = "Apples" ==> works fine,

search_string = "apples bananas" ==> 0 results as it tries to find exact string literal


I'm looking for a way to find all words (search_string.Split??) and return all matches.

The below works for single word searches currently,

public ActionResult Search(string search_string)
{ return view(db.AttributesTable.Where(
x => x.Description.Contains(search_string)).ToList());
}


Can someone please help me adapt this to return ANY of the words in ANY ORDER within the search_string?

i.e search_string (apples, bananas) or (bananas, apples) should return same results.

Thanks.

Answer

For very simple searches, you can use following code

var terms = search_string.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
IQueryable<Attributes> att = db.AttributesTable;

foreach(var term in terms)
{
    att = att.Where(x => x.Description.Contains(term));
}

return View(att.ToList());

It will return all rows that contains all words specified in search_string.


Edit

To return rows that contains ANY of the word in search_string you can build expression yourself. It's a little hard. but it's possible.

var terms = search_string.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);

var varExpr = Expression.Variable(typeof(YourClass), "x");

var strContainsMethodInfo = typeof(string).GetMethod("Contains");
var propInfo = typeof(YourClass).GetProperty("Description");

var falseExpr = (Expression) Expression.Constant(false);
var body = terms
    .Select(Expression.Constant)
    .Select(con => Expression.Call(Expression.Property(varExpr, propInfo), strContainsMethodInfo, con))
    .Aggregate(falseExpr, Expression.OrElse);

var lamb = (Expression<Func<YourClass, bool>>)Expression.Lambda(body, varExpr);
var att = db.AttributesTable
            .Where(lamb);

return View(att.ToList());

Change YourClass to your entity class i.e. Attribute or something.