eg: x=> x.Name = "g"
I have code block like this
public Expression<Func<TEntity, bool>> SearchExpression()
{
    var c = new ConstantExpression[_paramList.Count];
    var b = new BinaryExpression[_paramList.Count];
    BinaryExpression comparisonExpression = null;
    var entity = Expression.Parameter(typeof(TEntity));
    for (int i = 0; i < _paramList.Count; i++)
    {
        var value = Convert.ChangeType(_paramList[i].Item2 /*"g"*/, _paramList[i].Item3 /*System.String*/);
        c[i] = Expression.Constant(value); //"g"
        // PROBLEM IS HERE
        b[i] = Expression.Equal(Expression.Property(entity, _paramList[i].Item1 /*Name*/, c[i]);
        // PROBLEM IS HERE
    }
    _paramList.Clear();
    comparisonExpression = b.Aggregate(Expression.And);
    return Expression.Lambda<Func<TEntity, bool>>(comparisonExpression, entity);
}
works like charm but I need Expression.Like (Like "g" not Equal "g")
Expression.Like(Expression.Property(entity, _paramList[i].Item1), c[i])
but C# expression tree does not support Like method
UPDATE :
I wrote something like this :
Expression.Call(Expression.Property(entity, _paramList[i].Item1),
                typeof(String).GetMethod("Contains"), new Expression[] { c[i] });  
but I need BinaryExpression not MethodCallExpression
You can make your code work by adding an equals expression over the method call, like so:
    b[i] = Expression.Equal(
        Expression.Call(Expression.Property(entity, _paramList[i].Item1),
        typeof (String).GetMethod("Contains"), 
          new Expression[] {c[i]}), Expression.Constant(true));
In pseudo code this reads as:
b[i] = entity => entity.someProperty.Contains(c[i]) == true;
Which will return a binary expression for you.
This answer does not consider your array and the 'and' aggregation, but this should be considered as a separate issue.
Consider this class:
class MyEntity { string Name { get; set; } }
We want to query:
select ... from MyEntity where Name like '%query%';
The following method is a general implementation of the above query pattern:
static Expression<Func<TEntity, bool>> Like<TEntity>(string propertyName, string queryText)
{
    var parameter = Expression.Parameter(typeof (TEntity), "entity");
    var getter = Expression.Property(parameter, propertyName);
    //ToString is not supported in Linq-To-Entities, throw an exception if the property is not a string.
    if (getter.Type != typeof (string))
        throw new ArgumentException("Property must be a string");
    //string.Contains with string parameter.
    var stringContainsMethod = typeof (string).GetMethod("Contains", new[] {typeof (string)});
    var containsCall = Expression.Call(getter, stringContainsMethod,
        Expression.Constant(queryText, typeof (string)));
    return Expression.Lambda<Func<TEntity, bool>>(containsCall, parameter);
}
If you want to have a pattern of query% or %query you can use string.StartsWith and string.EndsWith instead of Contains.
Also, you can share the parameter across multiple calls if you adjust the signature.
The current implementation throws an exception if the data type of the property is not a string. Look at this answer https://stackoverflow.com/a/3292773/668272 for converting numbers to strings.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With