leora
leora

Reputation: 196891

can linq expression be case insensitive

i am leveraging this project to use jqgrid to filter and sort collections. The one missing feature is that this example is not doing case insensitive search which i need.

So if a user types in "Test" i want it to match with "TEST", "TeST", etc . .

i have code that looks like this:

            case WhereOperation.Equal:
                condition = Expression.Equal(memberAccessToString, filter);
                lambda = Expression.Lambda(condition, parameter);
                break;
            case WhereOperation.NotEqual:
                condition = Expression.NotEqual(memberAccessToString, filter);
                lambda = Expression.Lambda(condition, parameter);
                break;
            case WhereOperation.Contains:
                condition = Expression.Call(memberAccessToString,
                    typeof(string).GetMethod("Contains"),
                    Expression.Constant(value));
                lambda = Expression.Lambda(condition, parameter);
                break;

is there anyway to have these checks below being case insensitive so "Test" would equal "TEST"

Expression.NotEqual    
Expression.Equal
Expression.Call(memberAccessToString,
                    typeof(string).GetMethod("Contains"),

Upvotes: 13

Views: 12149

Answers (4)

Heinzi
Heinzi

Reputation: 172478

You could convert both values to lowercase before doing the comparison. Here's an example for Contains:

case WhereOperation.Contains:
    var toLower = Expression.Call(memberAccessToString,
                                  typeof(string).GetMethod("ToLower", System.Type.EmptyTypes));
    condition = Expression.Call(toLower,
                                typeof(string).GetMethod("Contains"),
                                Expression.Constant(value.ToString().ToLower()));
    lambda = Expression.Lambda(condition, parameter);
    break;

Note, however, that this won't pass the Turkey test.

Upvotes: 20

RouR
RouR

Reputation: 6336

case WhereOperation.Contains:
     var callEx = Expression.Call(memberAccess, typeof(string).GetMethod("IndexOf", new[] { typeof(string), typeof(StringComparison) }), Expression.Constant(value), Expression.Constant(StringComparison.OrdinalIgnoreCase));
     condition = Expression.NotEqual(callEx, Expression.Constant(-1));
     lambda = Expression.Lambda(condition, parameter);
     break;

Upvotes: 2

Atanu GB
Atanu GB

Reputation: 41

You get it following way:

First Extend string class:

internal static class StringExtensions

    {
        public static bool ContainsExt(this String str, string val)
        {
            return str.IndexOf(val, StringComparison.InvariantCultureIgnoreCase) > -1 ? true : false;
        }
    }

Now write Expression call as

Expression.Call(null,
                    typeof(StringExtensions).GetMethod("ContainsExt", new Type[] { typeof(String), typeof(String) }),
                    new[] { memberAccessToString, Expression.Constant(value));

Upvotes: 4

Andrew Hare
Andrew Hare

Reputation: 351758

Unfortunately the BCL does not have a Contains overload that allows you to specify case invariance. You will have to grab the correct overload of IndexOf as a workaround (checking to see if the result of IndexOf is greater than zero):

var methodInfo 
    = typeof(string)
        .GetMethod("IndexOf", 
            new[] { typeof(string), typeof(StringComparison) });

This MethodInfo accepts a string and a StringComparison which will allow you to specify StringComparison.OrdinalIgnoreCase if you wish.

Upvotes: 9

Related Questions