I want to build an expression tree with an equal that behaves as if it were in SQL. That is to say, I want it to ignore case of the strings e.g.:
"ThIs Is A tEsT"
, "tHiS iS a TeSt"
, "this is a test"
, and "THIS IS A TEST"
should all match to "this is a test"
.
public class Datum
{
public string Value { get; set; }
}
void Main()
{
var data = new List<Datum> {
new Datum { Value = "ThIs Is A tEsT" },
new Datum { Value = "tHiS iS a TeSt" },
new Datum { Value = "this is a test" },
new Datum { Value = "THIS IS A TEST" }
};
var queryableData = data.AsQueryable<Datum>();
var pe = Expression.Parameter(typeof(Datum), "Value");
var right = Expression.Constant("this is a test", typeof(string));
var e = Expression.Equal(Expression.Property(pe, "Value"), right);
var whereCallExpression = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { queryableData.ElementType },
queryableData.Expression,
Expression.Lambda<Func<Datum, bool>>(e, pe));
var results = queryableData.Provider.CreateQuery<Datum>(whereCallExpression);
results.Dump();
}
I have tried several things and nothing seems to be working.
I found the most direct way to accomplish this task is to Invoke a custom method like this:
public class Datum
{
public string Value { get; set; }
}
void Main()
{
var data = new List<Datum> {
new Datum { Value = "ThIs Is A tEsT" },
new Datum { Value = "tHiS iS a TeSt" },
new Datum { Value = "this is a test" },
new Datum { Value = "THIS IS A TEST" }
};
var queryableData = data.AsQueryable<Datum>();
var pe = Expression.Parameter(typeof(Datum), "Value");
var right = Expression.Constant("this is a test", typeof(string));
// * First build a func that will use the method you want. In this case, it is going to be any equals that ignores case.
// * Next Invoke that method instead of Expression.Equal.
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Expression<Func<string, string, bool>> IgnoreCase = (op1, op2) => op1.Equals(op2, StringComparison.OrdinalIgnoreCase);
var e = Expression.Invoke(IgnoreCase, Expression.Property(pe, "Value"), right);
//var e = Expression.Equal(Expression.Property(pe, "Value"), right);
var whereCallExpression = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { queryableData.ElementType },
queryableData.Expression,
Expression.Lambda<Func<Datum, bool>>(e, pe));
var results = queryableData.Provider.CreateQuery<Datum>(whereCallExpression);
results.Dump();
}