2

We have create this LinqExtension class to provide a Like method to Linq. Contains is not useful for us because we would like to do searchs like "%a%b%", in StackOverFlow we have found several post that are using method PatIndex from SqlFunction class to do It with Entity Framework.

To keep clean code and easy reusable we are trying to do an extension method to encapsulate PatIndex call

public static IQueryable<TSource> WhereLike<TSource>(
  this IQueryable<TSource> source,
  Expression<Func<TSource, string>> valueSelector,
  string value
)
{
  return source.Where(BuildLikeExpression(valueSelector, value));
}

public static Expression<Func<TElement, bool>> BuildLikeExpression<TElement>(
  Expression<Func<TElement, string>> valueSelector,
  string value
)
{
  if (valueSelector == null)
    throw new ArgumentNullException("valueSelector");

  var method = GetLikeMethod(value);

  var body = Expression.Call(method, valueSelector.Body, Expression.Constant(value));

  var parameter = valueSelector.Parameters.Single();
  var expressionConvert = Expression.Convert(Expression.Constant(0), typeof(int?));
  return Expression.Lambda<Func<TElement, bool>> (Expression.GreaterThan(body, expressionConvert));
}

private static MethodInfo GetLikeMethod(string value)
{
  var methodName = "PatIndex";
  Type stringType = typeof(SqlFunctions);
  return stringType.GetMethod(methodName);
}

The problem is when we call this new method we get the error Incorrect number of parameters supplied for lambda declaration at

return Expression.Lambda<Func<TElement, bool>> (Expression.GreaterThan(body, expressionConvert));

What are we missing to do it properly?

1 Answer 1

3

You're nearly there.

You've got the parameters in the wrong order for the call expression, and you need to pass the parameter to Expression.Lambda:

public static Expression<Func<TElement, bool>> BuildLikeExpression<TElement>( Expression<Func<TElement, string>> valueSelector, string value )
{
    if ( valueSelector == null )
        throw new ArgumentNullException( "valueSelector" );

    var method = GetLikeMethod( value );

    var body = Expression.Call( method, Expression.Constant( value ), valueSelector.Body );

    var parameter = valueSelector.Parameters.Single();
    var expressionConvert = Expression.Convert( Expression.Constant( 0 ), typeof( int? ) );

    return Expression.Lambda<Func<TElement, bool>>( Expression.GreaterThan( body, expressionConvert ), parameter );
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.