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

标签 c# .net linq 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 表达式将转换为表达式树而不是委托(delegate)。

然后您需要构建一个 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 谓词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3441422/

相关文章:

C# 关于 IEnumerable<T>.Aggregate

c# - 控制 USB 端口的电源?

c# - 在任务计划程序 2.0 中获取错误代码 -2147216615

c# - 在 C# 中合并 YAML

c# - Dictionary.FirstOrDefault() 如何确定是否找到结果

c# - LINQ to Entities 为实体的 child 的 child 返回错误的 ID

c# - 如何使用 Response.Redirect() 打开具有特定 div 的网页?

c# - 有没有办法用 C# 从另一个进程中删除关闭按钮?

c# - 无法在生产 ASP.net 站点上加载文件或程序集 Microsoft.SqlServer.SqlClrProvider,它在哪里?

c# - 委托(delegate)指向什么?