对于这个问题,我将使用Products的标准结构(带有IsActive标志)和OrderItems(每个都引用一个Product)。我还有一个查询构建器,它生成用于查询产品的Linq表达式。样本过滤器可让用户找到活动/非活动产品,生成Linq表达式,如:
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到实体)不支持Expression.Invoke
。
有没有办法从testProductActive
获取MemberExpression并将其转换为!orderItem.Product.IsActive
?
注意:在一个现实生活中的例子中,我将有一个由可见过滤器生成的Expression<Func<Product, bool>>
个表达式集合,这些表达式都需要转换。现在我已经让我的过滤器为两种类型的记录生成表达式,但是我希望删除重复并使其成为现有的过滤器可以用于不同类型的记录,而无需更改过滤器自己的代码。