Преобразование выражения в другое? - PullRequest
2 голосов
/ 15 мая 2019

У меня есть маленький вызов, который я не знаю, как решить.

Мне нужно конвертировать из Expression<Func<TEntity, URequest, bool>> в Expression<Func<TEntity, bool>>.

2-й будет использоваться для запроса источника данных.

Идея состоит в том, чтобы иметь конструктор базового класса со следующей подписью

abstract class Base
{
    Base(Expression<Func<TEntity, TRequest, bool>> expression) { .... }
}

Я могу предоставить выражение в производном что-то вроде этого

class Derived : Base 
{
   Derived() : 
        base ((enttiy, request) => entity.SomeProp == request.SomePropValue) { } 
}

Используется Базой как таковой

/// Ctor
Base(Expression<Func<TEntity, TRequest, bool>> expression)
{
    _pipelineBuilder.AddFetchEntityStep (expression)
}

Где AddFetchEntityStep - это шаг в конвейере

Трубопровод выглядит так.

Шаг 1: FetchEntity Шаг 2: Выполнение Шаг 3: Проверить Шаг 3: Выполнено

Теперь есть два способа получения сущности по Id или другому свойству.

Для этого у меня есть

ReadOnlyRepository
{
    TEntity GetById<TEntity>(object id) { .... } 
    TEntity GetBy<TEntity>(Expression<Func<TEntity, bool>> expression) { .... }

В AddFetchEntityStep я делаю проверку, чтобы узнать, что Get вызывает, что-то вроде

public void AddFetchEntityStep (Expression<Func<TEntity, URequest, bool>> expression = null)
{
     if (expression == null )
     {   
         _repo.GetById<TEntity>(1)
     }  

     else 
     {
         _repo.GetBy(.....) //// The problem 
     }
}

Я знаю, что это две разные подписи Expression<Func<TEntity,bool>> и Expression<Func<TEntity, TRequest, bool>>

1 Ответ

4 голосов
/ 16 мая 2019

Нельзя просто использовать лямбда-выражение для преобразования дерева выражений в другое.

Пока параметр запроса не предоставлен вызывающей стороной, которая задает лямбда-выражение, рассмотрите использование Func<URequest,Expression<Func<TEntity,bool>>> вместо Expression<Func<TEntity, URequest, bool>>.

И лямбда-выражение будет выглядеть так

(request) => (enttiy) => entity.SomeProp == request.SomePropValue.

Тогда ваш базовый класс может вызвать его, чтобы связать объект 'request' с выражением.

Кстати, имена общих параметров с префиксом, отличным от T, являются антипаттернами.

...