c# – 使用成员访问lambda表达式来参数化LINQ to SQL谓词

我有一个需要在整个地方重用的查询,我需要改变哪个属性/列用于连接.
我希望能做的是:
query = RestrictByProp(query, x=>x.ID);
极简化的RestrictByProp()可能是*:
private static IQueryable<Role> RestrictByProp(IQueryable<Role> query,
Func<Role, int> selector)
{
return query.Where(x => selector(x) == 1);
}
问题是即使这个简单的实现也会导致运行时异常:
Method 'System.Object DynamicInvoke(System.Object[])' has no
supported translation to SQL.
**(这里我只是添加一个简单的’where’子句 – 在我的实际代码中,我将使用lambda来选择要用于连接的属性.)*
我发现这很奇怪,因为如果成员访问lambda是内联完成的,那很好:
private static IQueryable<Role> RestrictByID(IQueryable<Role> query)
{
return query.Where(x=> x.ID == 1);
}
如果传入Expression< Func< Role,bool>>,LINQ to SQL也很高兴(即当参数是x => x.ID == 1时)但是因为我需要在查询中确定右手操作数的值而使对象失败.
有没有办法以某种方式在RestrictByProp()中使用lambda表达式,以便LINQ to SQL知道如何生成SQL?
解决方法:
首先,您需要更改方法签名:
private static IQueryable<Role> RestrictByProp(IQueryable<Role> query,
Expression<Func<Role, int>> selector)
这意味着您的lambda表达式将转换为表达式树而不是委托.
然后,您需要构建一个Expression< Func< Role,bool>>从现有的表达式树.
它看起来像这样:
LambdaExpression lambda = (LambdaExpression) selector;
var predicate = Expression.Equal(selector, Expression.Constant(1));
var lambdaPredicate = Expression.Lambda<Func<Role, bool>>(predicate,
lambda.Parameters);
return query.Where(lambdaPredicate);