Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Search on all fields of an entity

I'm trying to implement an "omnibox"-type search over a customer database where a single query should attempt to match any properties of a customer.

Here's some sample data to illustrate what I'm trying to achieve:

FirstName  | LastName  | PhoneNumber | ZipCode | ...
--------------------------------------------------
Mary       | Jane      | 12345       | 98765   | ...
Jane       | Fonda     | 54321       | 66666   | ...
Billy      | Kid       | 23455       | 12345   | ...
  • If the query was "Jane", I'd expect row #1 to be returned as well as row #2.
  • A query for 12345 would yield rows #1 and #3.

Right now, my code looks pretty much like this:

IEnumerable<Customer> searchResult = context.Customer.Where(
    c => c.FirstName   == query ||
         c.LastName    == query ||
         c.PhoneNumber == query ||
         c.ZipCode     == query
         // and so forth. Fugly, huh?
);

This obviously works. It smells like really bad practice to me, though, since any change in the Entity (removal of properties, introduction of new properties) would break stuff.

So: is there some LINQ-foo that will search across all properties of whatever Entity I throw at it?

like image 887
vzwick Avatar asked Oct 11 '12 17:10

vzwick


1 Answers

first find all properties within Customer class with same type as query:

var stringProperties = typeof(Customer).GetProperties().Where(prop =>
    prop.PropertyType == query.GetType());

then find all customers from context that has at least one property with value equal to query:

context.Customer.Where(customer => 
    stringProperties.Any(prop =>
        prop.GetValue(customer, null) == query));
like image 56
Bizhan Avatar answered Oct 04 '22 00:10

Bizhan