vendredi 23 novembre 2018

C# Reflection Expression Linq

I'm having some problems with C# dynamic generated lambda expressions.

Considering the following scenario:

public class Person {
    public long Id { get; set; }
    public string Name { get; set; }
}

List<Person> persons = new List<Person> () {
    new Person { Id = 1, Name = "Foo" },
    new Person { Id = 2, Name = "Bar" },
    new Person { Id = 3, Name = "Baz" },
    new Person { Id = 4, Name = null },
};

Now, doing the follow code

ParameterExpression param = Expression.Parameter(typeof(Person), "arg");
Expression prop = Expression.Property(param, "Name");
Expression value = Expression.Constant("bar");
Type type = prop.Type;

MethodInfo toLower = typeof(String).GetMethod("ToLower", Type.EmptyTypes);
Expression expLower = Expression.Call(prop, toLower);

Expression clausule = Expression.Call(expLower, type.GetMethod("Contains", new[] { type }), value);
Expression notNull = Expression.NotEqual(prop, Expression.Constant(null));

clausule = Expression.And(notNull, clausule);

var exp = Expression.Lambda<Func<T, bool>>(clausule, param);

The above code generate the following exp.

//arg => ((arg.Name != null) And (arg.Name.ToLower().Contains("bar")))

Now, trying to apply that to my list.

The filter below works

var filteredListThatWorks = persons.Where(arg => arg.Name != null && arg.Name.ToLower().Contains("bar")).ToList();

The one below throws exception of Null object ( because of Id 4 name)

var filteredListThatGivesExp = persons.Where(exp.Compile()).ToList();

The same expression, when generated by lambda, throws exp, when manually inputed, works. Anyone knows a way to solve that ?

Br,





Aucun commentaire:

Enregistrer un commentaire