2009-12-01 2 views
1

По этому вопросу я буду использовать стандартную структуру продуктов (с флагом IsActive) и OrderItems (каждая ссылка на Продукт). У меня также есть построитель запросов, который генерирует выражения Linq, используемые для запроса продуктов. Образец фильтр позволит пользователю найти активные/неактивные продукты, создавая выражение Linq, как:Преобразование Linq MemberExpression lambda для работы со классом со ссылкой

Expression<Func<Product, bool>> testProductActive = product => !product.IsActive; 

Я хочу, чтобы принять это выражение и использовать его для тестирования IQueryable<OrderItem>. Я могу сделать это с в памяти коллекции с помощью Expression.Invoke:

public static Expression<Func<TDestination, TResult>> Translate<TSource, TDestination, TResult>(this Expression<Func<TSource, TResult>> @this, Expression<Func<TDestination, TSource>> getSourceFromDestination) 
{ 
    ParameterExpression param = Expression.Parameter(typeof(TDestination), "arg"); 

    Expression invokedGetSource = Expression.Invoke(getSourceFromDestination, param); 
    Expression invokedOriginalBody = Expression.Invoke(@this, invokedGetSource); 

    Expression<Func<TDestination, TResult>> result = Expression.Lambda<Func<TDestination, TResult>>(invokedOriginalBody, param); 
    return result; 
} 

который я бы назвал так:

Expression<Func<OrderItem, bool>> testOrderItemProductActive = testProductActive.Translate<Product, OrderItem, bool>(orderItem => orderItem.Product); 

Но NHibernate.Linq (и от того, что я видел в вопросах, Linq к Entities) не поддерживает Expression.Invoke.

Есть ли способ взять MemberExpression от testProductActive и превратить его в !orderItem.Product.IsActive?


Примечания: В реальной жизни, например, я бы коллекция Expression<Func<Product, bool>> выражений, генерируемых видимые фильтры, которые будут преобразованы все потребности. Прямо сейчас у меня есть фильтры, генерирующие выражения для обоих типов записей, но я хотел бы отказаться от дублирования и сделать так, чтобы существующий фильтр можно было использовать для записи другого типа без изменения собственного кода фильтра.

+0

Был старый вопрос, который показал посетителю для объединения Expresson.Invoke - ищет его ... –

+2

Найдено это: http://stackoverflow.com/questions/1717444 - это позволит вам использовать 'Expression.Invoke', но сгладить его до одного (' Invoke'-free) 'Expression'. Не уверен, что это тогда обман? –

+0

@Mark, активируйте свой ответ, потому что он выглядит круто! –

ответ

0

Это не совсем то же ключе, что и то, что вы предлагаете, но проверить Dynamic Linq.

Смежные вопросы