How to create a dynamic 'contains or LIKE' Expression to be used with Linq against OData service
I'm try'n to create a dynamic query tool using System.Linq.Expressions.Expression (WPF/c#4.0) It runs against an OData Service.
So far, all is working as long as I limit the conditions to build in options like Equal(..), GreaterThan(..) etc. There seems to be no build in contains/Like condition so I tried building my own. There are a handful of articles already out there. One I tried is How to create a System.Linq.Expressions.Expression for Like?.
Now if I use the above solution, the resulting where expression is
whereCallExpression = {Convert([1开发者_开发知识库0000]).Expand("A,B").Where(clt => MyLike(clt.LastName, "te"))}'
which is nice, but wrong, since it does not translate into a valid Odata query.
If I use condition 'Equal', the result is
whereCallExpression = {Convert([10000]).Expand("A,B").Where(clt => (clt.LastName == "te"))}
which results in the OData query
results = {http://.../Clients()?$filter=LastName eq 'te'&$expand=A,B}
and is working as expected.
Am I doing something wrong with the implementation of the solution, or can it not be used with OData?
It should transfer to something like ...?$filter=substringof('te', LastName ) eq true
Any solution on how to fix this?
Regards
Andreas
PS, I implemented the solution extension in a static class, all I changed is the name of the called method from 'Like' to 'MyLike' Also, since the code used to build the expressions is working with any of the build-in condition, I assume, for now that part is ok. I can post parts of it if needed
OData currently doesn't support the "like" operator at all. So no matter what you do on the client, the URL produced has not way of expressing that. The substringof is supported and the client LINQ provider should generate it when you use string.Contains method in your filter (Where) expression.
To get the expression generated by a C# compiler you can do something like this:
IQueryable<string> source = new List<string>().AsQueryable();
IQueryable<string> result = from item in source where item.Contains("John") select item;
Console.WriteLine(result.Expression.ToString());
Basically any IQueryable has a property Expression which contains the expression tree for the query to run. Some LINQ providers might change the expression tree somewhat from the original one created by the compiler, but most should leave it close to the original.
精彩评论