хитрость в том, чтобы посмотреть, что делает компилятор, то есть скомпилировать что-то вроде:
using System.Linq;
public class C {
public void M() {
var query = Data.Where(x => x.Bar == "abc");
}
System.Linq.IQueryable<Foo> Data;
class Foo {
public string Bar {get;set;}
}
}
и посмотри, что он делает; если мы посмотрим в sharplab.io , то увидим:
public void M()
{
IQueryable<Foo> data = Data;
ParameterExpression parameterExpression = Expression.Parameter(typeof(Foo), "x");
BinaryExpression body = Expression.Equal(Expression.Property(parameterExpression, (MethodInfo)MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/)), Expression.Constant("abc", typeof(string)));
ParameterExpression[] obj = new ParameterExpression[1];
obj[0] = parameterExpression;
IQueryable<Foo> queryable = Queryable.Where(data, Expression.Lambda<Func<Foo, bool>>(body, obj));
}
и мы можем сделать вывод, что вы хотите что-то подобное, т.е.
var p = Expression.Parameter(typeof(T), "x");
var body = Expression.Equal(
Expression.PropertyOrField(p, Property),
Expression.Constant((object)value)
);
var lambda = Expression.Lambda<Func<T, bool>>(body, p);
return query.Where(lambda);