0

We don't have some kind of Expression.Like in c#. So as an alternative, I am doing below work:

private static readonly MethodInfo StringContains = typeof(string).GetMethod("Contains", new[] { typeof(string) });

and then using it with expression like:

var contExpressions = new List<Expression>();
var equals = nonNullValues.Select(value =>
                               (Expression) Expression.Call(left, StringContains, Expression.Constant(value, typeof(string)))).ToList();
                           contExpressions.AddRange(equals);

But this comparision is being case sensitive. I want the expression to ignore case.

The as an alternative, I tried using the indexof method as below:

private static readonly MethodInfo StringContainsIgnoreCase = typeof(string).GetMethod("IndexOf", new[] { typeof(string), typeof(StringComparison) });

and used with Expression as:

var equals = nonNullValues.Select(value =>
                            Expression.NotEqual(Expression.Call(left, StringContainsIgnoreCase, Expression.Constant(value, typeof(string)), Expression.Constant(StringComparison.OrdinalIgnoreCase)), Expression.Constant(-1))).ToList();
                        contExpressions.AddRange(equals);

And then tried to make the final expression as:

var expression = Expression.Lambda<Func<T, bool>>(contExpressions.Count == 1 ? contExpressions[0] : contExpressions.Aggregate(Expression.Or), parameter);

This works for some cases but for other it throws exception as:

LINQ could not be translated. could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync().

Can anyone help me where I am going wrong and how can I perform a case-insensitive contains check using Expression? Thanks in advance

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
BunnY
  • 41
  • 7
  • Does [this](https://stackoverflow.com/questions/43277868/entity-framework-core-contains-is-case-sensitive-or-case-insensitive) help? – Guru Stron Mar 16 '21 at 13:31
  • 1
    Why not just use: sSomeString.ToLower() on everything to ignore case? – JesseChunn Mar 16 '21 at 14:36
  • 1
    @JesseChunn Is that really possible while generating Expression, Expression.NotEqual will expect Expressions and thus not possible to call string methods on that – BunnY Mar 16 '21 at 15:20

1 Answers1

1

I was able to get this working as below:

private static readonly MethodInfo StringContainsIgnoreCase =typeof(DbFunctionsExtensions).GetMethod(nameof(DbFunctionsExtensions.Like), new[] { Expression.Property(null, typeof(EF).GetProperty(nameof(EF.Functions)) ??throw new InvalidOperationException()).Type, typeof(string), typeof(string)
    });

and then use below to make Expression:

var equals = nonNullValues.Select(value =>
                        Expression.Call(null, StringContainsIgnoreCase, Expression.Property(null, typeof(EF), nameof(EF.Functions)), left, Expression.Constant($"%{value}%", typeof(string)))).ToList();
                    contExpressions.AddRange(equals);

This works like charm when you need to have a Expression to perform a string case insensitive contains work.

BunnY
  • 41
  • 7