C# generic search extension method for IQueryable
less than a minute read
Now available as a nuget package. Search for 'SearchExtensions' or run the following:
<p class="nuget-badge"><code>PM> Install-Package NinjaNye.SearchExtensions</code></p> **Source code can be found here: [https://github.com/ninjanye/searchextensions](https://github.com/ninjanye/searchextensions)**Following on from my previous post on creating a generic repository method, I decided to take it a step further and create an generic search extension method to perform the same task.
Here is the code:
public static class QueryableExtensions
{
public static IQueryable<T> Search<T>(this IQueryable<T> source, Expression<Func<T, string>> stringProperty, string searchTerm)
{
if (String.IsNullOrEmpty(searchTerm))
{
return source;
}
// The below represents the following lamda:
// source.Where(x => x.[property] != null
// && x.[property].Contains(searchTerm))
//Create expression to represent x.[property] != null
var isNotNullExpression = Expression.NotEqual(stringProperty.Body,
Expression.Constant(null));
//Create expression to represent x.[property].Contains(searchTerm)
var searchTermExpression = Expression.Constant(searchTerm);
var checkContainsExpression = Expression.Call(stringProperty.Body, typeof(string).GetMethod("Contains"), searchTermExpression);
//Join not null and contains expressions
var notNullAndContainsExpression = Expression.AndAlso(isNotNullExpression, checkContainsExpression);
var methodCallExpression = Expression.Call(typeof(Queryable),
"Where",
new Type[] { source.ElementType },
source.Expression,
Expression.Lambda<Func<T, bool>>(notNullAndContainsExpression, stringProperty.Parameters));
return source.Provider.CreateQuery<T>(methodCallExpression);
}
}
Performing the following code against a DBContext (connected to a sql db):
string searchTerm = "test";
var results = context.Clubs.Search(club => club.Name, searchTerm).ToList();
Which produces the following SQL:
SELECT [Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name]
FROM [dbo].[Clubs] AS [Extent1]
WHERE ([Extent1].[Name] IS NOT NULL)
AND ([Extent1].[Name] LIKE N'%test%')
My next goal is to create an extension method that allows the user to pass multiple properties. The results will then match any of the supplied properties. Stay tuned...