我们创建了这个LinqExtension类,为Linq提供了一个Like方法。包含对我们没有用,因为我们想做“%a%b%”之类的搜索,在StackOverFlow中我们发现了几个使用SqlFunction类的方法PatIndex来实现它与Entity Framework的帖子。
为了保持代码清晰且易于重用,我们正在尝试使用扩展方法来封装PatIndex调用
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);
}
问题是当我们调用这个新方法时,我们得到错误
提供的用于lambda声明的参数数量不正确return Expression.Lambda<Func<TElement, bool>> (Expression.GreaterThan(body, expressionConvert));
我们缺少什么才能正确地做到这一点?
答案 0 :(得分:3)
你快到了。
您的调用表达式的参数顺序错误,您需要将参数传递给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 );
}