Mehdi Haghshenas
Mehdi Haghshenas

Reputation: 2447

Get Generic method "Contains" With IgonreCase when Create Dynamic LambdaExression

I want to create dynamic Lambda Expression for Method Call Contains for list of string values, the below code work's fine but not ignored string Case Sensitive

ParameterExpression parameter = Expression.Parameter(typeof(E), "x");
IQueryable<E> itemsToFilter = null; //this parameter set from input parameters
parameterName = "Name"; //this parameter set from input parameters
var prop = typeof(E).GetProperty(parameterName, BindingFlags.SetProperty | BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
MemberExpression propertyExp=Expression.Property(param, parameterName);
var genericListType = typeof(List<>).MakeGenericType(typeof(string));
IList tmplist = (IList)Activator.CreateInstance(genericListType);
foreach (var obj in orcond.Values)
{
   tmplist.Add(obj);
}
methodin = tmplist.GetType().GetMethod("Contains");
var list = Expression.Constant(tmplist);
var containsMethodExpin = Expression.Call(list, methodin, propertyExp);
comparison = Expression.Lambda<Func<E, bool>>(containsMethodExpin, parameter)
itemsToFilter.Where(comparison);

Note that the above code worked only for entity framework IQueryable but not worked for C# List

then I want to compare string in list with IgnoreCase

I want to call Contains with StringComparer.OrdinalIgnoreCase but when I use

methodin = typeof(List<string>).GetMethod("Contains", new Type[] { typeof(string), typeof(IEqualityComparer<string>) });

'methodin' returns null Please help how to get Contains with IEqualityComparer with correct reflection use.

Upvotes: 0

Views: 1356

Answers (2)

Coolicky
Coolicky

Reputation: 21

To invoke get the method with StringComparison just use

var property = "NameOfYourProperty"
var parameter = Expression.Parameter(typeof(T), "t");
var member = Expression.Property(parameter, property);
var method = typeof(string)
             .GetMethod("Contains", 
                 new[] { typeof(string), typeof(StringComparison) });

Then create your constants

var textConstant = Expression.Constant(searchText, typeof(string));           
var ignoreCaseConst = Expression.Constant(StringComparison.OrdinalIgnoreCase,
                                     typeof(StringComparison));

And call

var call = Expression.Call(member, method, textConstant, ignoreCaseConst);

Upvotes: 1

ferc
ferc

Reputation: 558

To find the "Contains" method with the EqualityComparer parameter, you can do:

MethodInfo Method = null;

foreach (var m in typeof(Enumerable).GetMethods())
{
    if (m.Name == "Contains" && m.GetParameters().Length == 3)
    {
        Method = m.MakeGenericMethod(typeof(string));
    }
}

And then you can use it like so:

var l = new List<string>() { "a", "b" };
var Result = (bool)Method.Invoke(null, new object[] { l, "a", EqualityComparer<string>.Default });

Upvotes: 2

Related Questions