I have a interface resembling the following:
public IEnumerable<IDocument> Search(Predicate<IDocument> predicate) { ... }
where an IDocument looks like this:
public interface IDocument
{
string Id {get; set;}
string Title {get; set;}
...
}
I am about to implement a document provider where I have to decompose the content of the Predicate and extract the properties in order to make an SQL string for a document database to which we currently have no OR/M mapping. An example: I want to know if the user is searching by ID or by Title so I know if I can search by ID or have to perform a LIKE search on Title.
I’ve always used LINQ heavily but this is the first time I’m sitting in the other end of the pipeline… I’ve read up a bit on Expression trees and Reflection but the pieces haven’t fallen in place yet. How (if?) can I decompose/reflect the Predicate so I get a list of parameters which I can concactate into an SQL string? I am looking for something like this rough sketch:
public IEnumerable<IDocument> Search(Predicate<IDocument> predicate)
{
string id = DoSomeMagic(predicate, "Id");
string title = DoSomeMagic(predicate, "Title");
if (!string.isNullOrEmpty(id))
...make ID search
else
...search by title
}
Disclaimer: The provider is for an inhouse legacy system bound for replacement this fall which makes inline SQL a proper choice ;o)
You can’t easily introspect the predicate. Maybe you should consider changing your design into a more ad hoc predicate type, a more specific predicate interface :
Replace the public fields with attributes, put the search logic in the SearchCriteria (e.g. .GetResult() or .GetSQLQuery()) and this may fit your system, assuming you can know all the available search criteria.