I need to create a dynamic linq expression for a dynamic search against an OData web service. The basic search is working but there are nested tables where it doesn't work.
The format is webservice/Books('id')/Author
I can get this to work
var authors = from p in webservice.Books.Expand("Author")
where p.Title.Equals("Watership Down") && p.Author.FirstName.Equals("Richard")
select p;
I have changed it to the following:
var authors = webservice.Books.Expand("Author").Where(condition);
and I construct condition as follows:
ParameterExpression pe = Expression.Parameter(typeof(webservice.Books), "p");
Expression left = Expression.Property(pe, "Title");
Expression right = Expression.Constant("Watership Down");
Expression predicateBody = Expression.Equal(left, right);
Expression<Func<webservice.Books, bool>> condition = Expression.Lambda
<Func<webservice.Books, bool>>(predicateBody, new ParameterExpression[] { pe });
Which works.
So if I try
ParameterExpression pe = Expression.Parameter(typeof(webservice.Books), "p");
Expression left = Expression.Property(pe, "Title");
Expression right = Expression.Constant("Watership Down");
Expression e = Expression.Equal(left, right);
left = Expression.Property(pe, "Author.FirstName");
right = Expression.Constant("Richard");
Expression e2 = Expression.Equal(left, right);
Expression predicateBody = Expression.And(e, e2);
Expression<Func<webservice.Books, bool>> condition = Expression.Lambda
<Func<webservice.Books, bool>>(predicateBody, new ParameterExpression[] { pe });
But it doesn't work. It doesn't recognize Author.FirstName as a property. I think it is because I declare pe as a type Books and so it doesn't see the nested Author but I can't figure out how to declare it so it will see the nested data.
The exact error message is Instance property 'Author.FirstName' is not defined for type 'webServices.Books'
Does anyone know how to do this? Is it even possible? Thanks for any help anyone can offer with this.
What I had to do to solve this error was to change left = Expression.Property(pe, "Author.FirstName"); to Expression property = Expression.Property(pe, "Author"); left = Expression.Property(property, "FirstName");
And now it works!
Thanks!