Как создать динамическое выражение Linq на основе лямбда из строки в C #?

У меня возникли трудности с созданием выражений Linq на основе лямбда-выражений из строки. Вот мой основной случай использования этого образца объекта / класса:

public class MockClass
{
    public string CreateBy { get; set; }
}

В основном мне нужно преобразовать такую ​​строку:

string stringToConvert = “x => x.CreateBy.Equals(filter.Value, StringComparison.OrdinalIgnoreCase”;

В выражение предиката / linq:

System.Linq.Expressions.Expression<Func<T, bool>>  or in this example 
System.Linq.Expressions.Expression<Func<MockClass, bool>>

Таким образом, это эквивалентно выражению Linq внутри метода Where ниже:

query = query.Where(x => x.CreateBy.Equals(filter.Value,
StringComparison.OrdinalIgnoreCase));

Я пробовал использовать следующие помощники, но, похоже, не могу понять, как заставить их работать в этом типе случая, когда я хочу иметь возможность построить выражение linq из строки, которая не известна заранее: http://www.albahari.com/nutshell/predicatebuilder.aspx

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx (это теперь доступен как пакет NuGet, также называемый «DynamicQuery»)


person jon333    schedule 11.04.2012    source источник
comment
Почему вы вообще помещаете выражение в строку? Пользователь вводит это выражение? Сохраните его в надлежащем виде.   -  person Travis J    schedule 12.04.2012
comment
Пользователь, не являющийся разработчиком, динамически вводит синтаксис запроса, который аналогичен синтаксису поиска, который передается в строке запроса, а затем должен в конечном итоге сделать все это, например Немного сложнее получить правильный тип, когда это может быть любое свойство или подсвойство огромного количества типов и вложенных типов.   -  person jon333    schedule 13.04.2012


Ответы (1)


Здесь был задан аналогичный вопрос:

Есть ли простой способ преобразовать строку (лямбда-выражения) в делегат действия?

Насколько я понимаю, этот «динамический запрос» на самом деле является основой для передачи ограничений для предложения Where без использования лямбда-выражения.

Смысл этого в том, что лямбда-выражения не являются динамическими методами, это анонимные методы. Если вы когда-нибудь взглянете на сборку, вы увидите, что ваши лямбда-выражения преобразуются в замыкания с любыми свободными переменными в качестве полей. В классе есть метод с подписью, соответствующей вашей, переменные поля назначаются в момент вызова.

Один хороший способ подумать об этом состоит в том, что это означает, что ваше лямбда-выражение интерпретируется компилятором C # во время компиляции, а переменные разрешаются путем создания экземпляра объекта из этого класса во время выполнения.

Чтобы продемонстрировать это, рассмотрим следующее:

var myLambda = x => x * x

Вы заметите, что это не работает. Это потому, что для создания связанного класса / метода компилятор должен знать во время компиляции тип x.

Все это важно, потому что понятие лямбда-выражения не существует в среде CLR во время выполнения (в той же форме, что и в коде). Строка, которая выглядит как лямбда-выражение, как раз и есть ...

person Sprague    schedule 11.04.2012
comment
Это работает для свойств верхнего уровня, использующих библиотеку Dynamic Linq, но я не могу получить субсвойства или субколлекции для замены. var test = string.Format ({0} == {1}, propertyName, value); var e = DynamicExpression.ParseLambda ‹EF.Discount, bool› (тест); Я хотел бы получить что-то вроде этого для перевода: query = query.Where (x = ›x.MockClass.SubCollection.Any (y =› y.Name.StartsWith (filter.Value))); - person jon333; 13.04.2012