Monday, April 25, 2011

Difference between Expression.Call overloads?

Hi,

I was attempting to dynamically create a Where predicate for a LINQ2SQL query:

...Where(SqlMethods.Like(r.Name, "%A%") ||
         SqlMethods.Like(r.Name, "%B%") ||
         SqlMethods.Like(r.Name, "%C%") || ...)

A, B, C, etc. come from some array. So I tried the following:

var roleExpression = Expression.Parameter(typeof(Role), r);
var nameExpression = Expression.Property(roleExpression, "Name");
var termExpression = Expression.Constant("%" + term[i] + "%");
var likeExpression = Expression.Call(
    typeof(SqlMethods), "Like",
    new[] { typeof(string), typeof(string) }, nameExpression, termExpression);

However, the last line fails with the message No method 'Like' on type 'System.Data.Linq.SqlClient.SqlMethods' is compatible with the supplied arguments.

So I tried the following line:

var likeExpression = Expression.Call(null,
    typeof(SqlMethods).GetMethod("Like", new[] { typeof(string), typeof(string) }),
    nameExpression, searchTermExpression)

This works. However, I don't understand what the difference is between these two lines. In my opinion they should deliver the same result.

Could anyone explain this?

Kind regards,
Ronald Wildenberg

From stackoverflow
  • I believe that the Type[] argument is for generic type parameters - i.e. you were trying to call:

    SqlMethods.Like<string,string>(...); // note the <string,string>
    

    Try passing an empty Type[].


    Edit re the confusion (comments); my point is: you shouldn't be specifying anything for the Type[] argument. Either an empty array or null would do; for example:

    var likeExpression = Expression.Call(
        typeof(SqlMethods), "Like", null, nameExpression, termExpression);
    
    Ronald Wildenberg : There is no SqlMethods.Like method that accepts generic type arguments, so this can not be the difference between both calls.
    Marc Gravell : You missed the point of my reply... it is preciseley ***because*** of this that it fails... (generic type args)
    Ronald Wildenberg : Ah, I see. As always it's a matter of reading the documentation carefully. Thanks for your reply.
    Ronald Wildenberg : I'm very sorry, but I do not have enough reputation to vote up your answer... I'll come back as soon as I have.
    Marc Gravell : No problem - feel free to mark as answered if you like, though... (the tick)
  • You can use the PredicateBuilder class from Joseph Albahari and Ben Albahari to build your where predicate

  • The answer is the next: Expression.Call(Nothing, GetType(System.Data.Linq.SqlClient.SqlMethods).GetMethod("Like", New Type() {GetType(String), GetType(String)}), New Expression() {left, right})

    Ronald Wildenberg : I'm afraid my Spanish isn't that good...

0 comments:

Post a Comment