2011-12-14

Expression Trees: Трансформация переменных в константы

Работая над кешированием LINQ to Entities запросов (см. пост про protobuf-net) я столкнулся с проблемой вычисления уникального ключа запроса. В рамках этой проблемы необходимо было решить две задачи, связанные с обработкой LambdaExpression-ов в IQueryable, для которого генерируется ключ:

  1. Для одинаковых лямбда-выражений, зависящих от переменной с разными значениями, должны генерироваться разные ключи.
  2. Для разных лямбда-выражений, зависящих от переменных с одинаковыми значениями, должны генерироваться одинаковые ключи.

Эти задачи можно сформулировать в виде кода:

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

Этот код «отрезает» лямбда-выражение от контекста, в котором оно было создано, и превращает все замкнутые в выражении переменные в константы. Кроме генерации уникального ключа по выражению приведённый выше код можно, например, использовать в своём Query Provider-е для примитивной нормализации лямбда-выражений и получения значений всех параметров запроса.

Комментариев нет:

Отправить комментарий