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

我有一个需要在整个地方重用的查询,我需要改变哪个属性/列用于连接.我希望能做的是:query = RestrictByProp(query, x=x.ID);极简化的RestrictByProp()可能是*:private static IQueryableRole RestrictByProp(I...

我有一个需要在整个地方重用的查询,我需要改变哪个属性/列用于连接.

我希望能做的是:

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);

本文标题为:c# – 使用成员访问lambda表达式来参数化LINQ to SQL谓词

基础教程推荐