Reputation: 159
I have an entity Car
with 3 searchable properties:
Brand Model Code
----------- ---------------- -----------
Ferrari F40 X7844ADFS
Porsche 911 Turbo YSAD42313
And I have the following method:
public IEnumerable<Car> SearchCar(string search)
{
IEnumerable<Car> result = Enumerable.Empty<Car>().AsEnumerable();
if (!string.IsNullOrEmpty(search))
{
var preResult = from A in _context.Cars
select new { TextField = A.Brand + " " + A.Model + A.Code,
car = A};
result = preResult.Where(x => x.TextField.ToLower().Contains(searchValue.ToLower())).Select(v => v.Car);
}
return result;
}
Example of searches :
This method, however, doesn't work for the first one (Porsche Turbo). Is there anyway to do this so that it works in all cases?
Upvotes: 2
Views: 72
Reputation: 3002
An alternative answer to IronMan84, which I think will be more efficient as it doesn't concatenate all the fields before searching on them. Creating the anonymous type with TextField and the car is unnecessary as you only return the car. Are you sure the object in the context is called Persons and not Cars?
public IEnumerable<Car> SearchCar(string search)
{
if (string.IsNullOrEmpty(search)) return Enumerable.Empty<Car>().AsEnumerable();
var terms = search.ToLower().Split(' ');
return _context.Cars
.Where(x => terms.All(t =>
x.Brand.ToLower().Contains(t)
|| x.Model.ToLower().Contains(t)
|| x.Code.ToLower().Contains(t)));
}
Also note that if you are connecting to a database with a case-insensitive collation then you can leave out ToLower() in all cases.
Upvotes: 1
Reputation: 16137
You would need to split the different words that are in the search
variable, and then search on those individually. Something like this:
var splitSearch = search.Split(' ');
result = preResult.Where(x => splitSearch.All(s => x.TextField.ToLower().Contains(s)))
.Select(v => v.Car);
Upvotes: 5