I'm trying to build a predicate builder which return a predicate that checks whether a list of ints contains another list of ints. So far I have this
public static Expression<Func<T, bool>> DynamicIntContains<T, TProperty>(string property, IEnumerable<TProperty> items)
{
var pe = Expression.Parameter(typeof(T));
var me = Expression.Property(pe, property);
var ce = Expression.Constant(items);
var call = Expression.Call(typeof(List<int>), typeof(List<int>).GetMethod("Contains").Name, new[] { typeof(int) }, ce, me);
return Expression.Lambda<Func<T, bool>>(call, pe);
}
T is the search object which contains a list of Ids as one of it's properties. TProperty is a list of ints and property is the name of the list on the property.The error I am getting is
Additional information: No method 'Contains' exists on type 'System.Collections.Generic.List`1[System.Int32]'.
Is this because I am calling it from a static method? Or am I trying to access the method on the typeof(List) incorrectly? Thanks.
Here is the solution;
public static Expression<Func<T, bool>> DynamicIntContains<T, TProperty>(string property, IEnumerable<TProperty> items, object source, PropertyInfo propertyInfo)
{
var pe = Expression.Parameter(typeof(T));
var me = Expression.Property(pe, property.Singularise());
var ce = Expression.Constant(propertyInfo.GetValue(source, null), typeof(List<int>));
var convertExpression = Expression.Convert(me, typeof(int));
var call = Expression.Call(ce, "Contains", new Type[] { }, convertExpression);
return Expression.Lambda<Func<T, bool>>(call, pe);
}
This works off the assumption that the list name is the plural of it's members. In Expression.Call I was passing a typeof(List), the correct method is to pass in Type[]. It seems to also be a requirement to convert the MemberExpression to a constant of a particular type. Thanks.