Lets say that I have a particular way of deciding whether some strings “match”, like this:
public bool stringsMatch(string searchFor, string searchIn)
{
if (string.IsNullOrEmpty(searchFor))
{
return true;
}
return searchIn != null &&
(searchIn.Trim().ToLower().StartsWith(searchFor.Trim().ToLower()) ||
searchIn.Contains(" " + searchFor));
}
I would like to pull matches out of a database using Linq To Entities and this helper. However, when I try this:
IQueryable<Blah> blahs = query.Where(b => stringsMatch(searchText, b.Name);
I get “LINQ to Entities does not recognize the method…”
If I re-write the code as:
IQueryable<Blah> blahs = query.Where(b =>
string.IsNullOrEmpty(searchText) ||
(b.Name != null &&
(b.Name.Trim().ToLower().StartsWith(searchText.Trim().ToLower()) ||
b.Name.Contains(" " + searchText)));
Which is logically equivalent, then things work fine. The problem is that the code isn’t as readable, and I have to re-write it for each different entity I want to match.
As far as I can tell from questions like this one, what I want to do is impossible at the moment, but I’m hoping that I’m missing something, am I?
Using a freely available library called LINQKit (as mentioned by @Eranga) this task becomes reasonable. Using LINQKit the code I have now looks like:
And needs to be called like this (note the AsExpandable() call)
The magic parts are the searchIn.Invoke(e) calls and the use of AsExpandable() which adds a wrapper layer that allows them to work.
The AsExpandable() bit is explained in detail by the original author here.
Note that I’m still a bit hazy on some of the details of expressions, so please add a comment/edit this answer if it can be made better/shorter/clearer.