The standard search method on IRavenQueryable looks like this:
public static IRavenQueryable<T> Search<T>(this IQueryable<T> self, Expression<Func<T, object>> fieldSelector, string searchTerms, decimal boost = 1m, SearchOptions options = SearchOptions.Guess, SearchOperator @operator = SearchOperator.Or)
{
MethodInfo method = (MethodInfo)MethodBase.GetCurrentMethod();
return (IRavenQueryable<T>)self.Provider.CreateQuery(Expression.Call(null, method, self.Expression, fieldSelector, Expression.Constant(searchTerms), Expression.Constant(boost), Expression.Constant(options), Expression.Constant(@operator)));
}
I’d like to create another extension method that allows me to specify which property to search on using its name. So I came up with this
public static IRavenQueryable<T> Search<T>(this IQueryable<T> self, string fieldName, string searchTerms, decimal boost = 1m, SearchOptions options = SearchOptions.Guess, SearchOperator @operator = SearchOperator.Or)
{
MethodInfo method = (MethodInfo)MethodBase.GetCurrentMethod();
var info = typeof(T).GetProperty(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
?? throw new Exception($"{fieldName} is not a valid property on {typeof(T).Name}");
var parTarget = Expression.Parameter(info.DeclaringType, "target");
var exprGetter = Expression.Lambda(typeof(Func<,>).MakeGenericType(info.DeclaringType, typeof(object)), Expression.Property(parTarget, info), parTarget);
return (IRavenQueryable<T>)self.Provider.CreateQuery(Expression.Call(null, method, self.Expression, exprGetter, Expression.Constant(searchTerms), Expression.Constant(boost), Expression.Constant(options), Expression.Constant(@operator)));
}
If I call this, I’m getting an ArgumentException (the Search I’m making is on T being NoSqlModels.PhoneBookCategory, and the property used in fieldName
is of type string)
System.ArgumentException: ‘Expression of type
‘System.Func2[NoSqlModels.PhoneBookCategory,System.String]' cannot be used for parameter of type 'System.String' of method 'Raven.Client.Documents.Linq.IRavenQueryable
1[NoSqlModels.PhoneBookCategory]
Search[PhoneBookCategory](System.Linq.IQueryable`1[NoSqlModels.PhoneBookCategory],
System.String, System.String, System.Decimal,
Raven.Client.Documents.SearchOptions,
Raven.Client.Documents.Queries.SearchOperator)’ (Parameter
‘arguments[1]’)’
So it seems that my exprGetter
returns an Expression<T,string>, rather than the required Expression<T,object>. So what do I need to change to get this to work