ToUpper() в Expression.Call

Код ниже работает, но я хотел бы представить ToUpper()

var predicate =
    Expression.Lambda<Func<T, bool>>(
        Expression.Call(
            Expression.PropertyOrField(parameter, "FirstName"),
            "Contains", null,
            Expression.Constant("myvalue".ToUpper())), parameter
        );

Результат:

{Param_0 => Param_0.FirstName.Contains("MYVALUE")}

Но я бы хотел это:

{Param_0 => Param_0.FirstName.ToUpper().Contains("MYVALUE")}

Как я могу изменить?

2 ответа

Решение

Просто добавьте Expression.Call:

var predicate =
    Expression.Lambda<Func<T, bool>>(
        Expression.Call(
            Expression.Call( // <=== this one is new
                Expression.PropertyOrField(parameter, "FirstName"),
                "ToUpper", null),
            "Contains", null,
            Expression.Constant("myvalue".ToUpper())), parameter
        );

который затем сообщает о себе как:

Param_0 => Param_0.FirstName.ToUpper().Contains("MYVALUE")

РЕДАКТИРОВАТЬ: Хорошо, я бы неправильно понял вопрос. Проблема в том, что ты звонишь Contains непосредственно на результат вызова FirstName имущество. Вам нужно позвонить ToUpper на имущество сначала, например

var firstName = Expression.PropertyOrField(parameter, "FirstName");
var firstNameUpper = Expression.Call(firstName, "ToUpper", null);
var target = Expression.Constant("myvalue".ToUpper());
var contains = Expression.Call(firstNameToUpper, "Contains", null, target);
var lambda = Expression.Lambda<Func<T, bool>>(contains, parameter);

Обратите внимание, что это не "культурно-безопасно" - было бы безопаснее использовать сравнение без учета регистра. Этот вопрос показывает подход с использованием IndexOf, но это может не поддерживаться вашим поставщиком LINQ (я не знаю, что вы будете делать с этим деревом выражений впоследствии).

Другие вопросы по тегам