'google-like' search with an IQueryable made even simpler
A little bit ago, I came out with this post:
Universal IQueryable Search Usable by Linq-to-SQL and Linq-to-Entities
and it worked great, but it got me thinking: if I could implement Reflection, it could be even easier to use and require less code to run as it would get the property names/types automatically.
So here I am with the new version and it is working great, it has already saved me lots of time.
All of the old overloads work as they did previously, I have just added some more.
Here is how a few of them work:
single-level search
Now that reflection is being used, you can pass any sorts of objects to the search and it will only compare like-types, no need to specify.
If you are trying to search a collection of 'car' objects in an IQueryable named 'cars' you can just do something like this:
Search(object[] keywords)
That will run through all of the properties of 'car', and if any of them are string variables, they will get compared against "chevy" and if they are Int32 variables, they will get compared against 2007. So this search would pull out all 2007 models made by Chevy.
Search(object[] keywords)
var results = cars.Search(new object[] {"chevy", 2007});
That will run through all of the properties of 'car', and if any of them are string variables, they will get compared against "chevy" and if they are Int32 variables, they will get compared against 2007. So this search would pull out all 2007 models made by Chevy.
search for specific properties
The above search will search all the properties of an object, but what if 'car' has 100 properties, and you only want to search 2, that is simple as well with this overload:
Search(string[] properties_to_search, object[] keywords)
Which will only search the properties 'make' and 'year' for the objects; only comparing like Types.
Search(string[] properties_to_search, object[] keywords)
var results = cars.Search( new string[] {"make", "year"}, new object[] {"chevy", 2007});
Which will only search the properties 'make' and 'year' for the objects; only comparing like Types.
multi-level search
Now let's say that the object 'car' has a some objects that you want to dig into as properties.
The 'car' object has an 'engine' property, but if we run the searches above, it will not drill down into the 'engine' object (though it would compare it if you sent an 'engine' as part of the search array).
To get it to drill into the engine object, we need to add another parameter, the Type[] types_to_explore so the Search knows to drill down into objects of that type:
Search(object[] keywords, Type[] types_to_explore)
Now the Search will search anything in the 'car' object and/or in the 'engine' since it now knows to look inside of it; not to mention it will recursively search down into the objects. This would even find something nested like this:
Since you told it to explore all 'engine' types. This would work even if you wanted to search into string, Int32, bool, etc. Types as they all have lots of properties in the world of Reflection - could be a whole new use for this extension?
Search(object[] keywords, Type[] types_to_explore)
var results = cars.Search( new object[] {"V8"}, new Type[] { typeof(engine) });
Now the Search will search anything in the 'car' object and/or in the 'engine' since it now knows to look inside of it; not to mention it will recursively search down into the objects. This would even find something nested like this:
car
-engine
-engine
-style:"V8"
Since you told it to explore all 'engine' types. This would work even if you wanted to search into string, Int32, bool, etc. Types as they all have lots of properties in the world of Reflection - could be a whole new use for this extension?
multi-level search on limited properties
Basically combine what was covered above:
Search(string[] types_to_explore, object[] keywords, Type[] types_to_explore)
I like this one the least as you have to be most verbose (but not as verbose as the other overloads). If you simply try to search for 'style' here, it will not be found, because you did not tell it to search 'engine' (the property, not the type).
Search(string[] types_to_explore, object[] keywords, Type[] types_to_explore)
var results = cars.Search( new string[] {"engine", "style"}, new object[] {"V8"}, new Type[] { typeof(engine) });
I like this one the least as you have to be most verbose (but not as verbose as the other overloads). If you simply try to search for 'style' here, it will not be found, because you did not tell it to search 'engine' (the property, not the type).
so that's the latest
If you haven't looked at the last post, I highly recommend you do, as it is still the most detailed search overloads are explained there (though a bit tougher to use).
This is very hard to explain, so I hope you just take a look at the code yourself or better yet, just try it out, you can see with trial and error how it works better than I can explain in a wordy blog.
As always, I am very interested in feedback and improvements!
Image may be NSFW.Clik here to view.
Clik here to view.