asp.net-mvc - 如何将 LINQ 表达式传递给返回 IQueryable 的函数
问题描述
我有一些方法可以作用于一个查询,一个是简单的 where 过滤器,另一个是带有要在 where 过滤器中使用的表达式的表达式,第三个也有一个表达式作为参数。
public static IQueryable<Employee> FilterExpression(this IQueryable<Employee> employees,
Expression<Func<Employee, Boolean>> expression)
{
return employees.Where(expression);
}
public static IQueryable<Employee> Active(this IQueryable<Employee> employees)
{
return employees.Where(e => e.IsActive);
}
前两个执行良好,没有任何问题。
var active = db.Employees.Active().Take(5).ToList();
var activeExpression = db.Employees.Take(5).FilterExpression((e) => e.IsActive).ToList();
下一个在另一个扩展方法中被调用,该方法返回一个任务集合上的选择的委托。
public static Expression<Func<SpwTask, TaskView>> Tasks(this TaskService service)
{
return (x) => new TaskView()
{
NotifyList = db.TaskContacts.JoinedEmployees
(t => t.TaskId == x.Id).Select(Projections.SimpleEmployees)
};
}
public static IQueryable<Employee> JoinedEmployees(this IQueryable<TaskContact> contacts,
Expression<Func<TaskContact, Boolean>> expression)
{
var id = ServicesRoot.Company.Id;
return from c in contacts.Where(expression)
join e in db.Employees on c.EmployeeId equals e.Id
where e.CompanyId == id
select e;
}
调用代码如下所示
// db is the DbContext and the Tasks is the extension method
...
return db.Tasks.Select(this.Tasks());
...
我得到的错误是这样的:
System.NotSupportedException:'LINQ to Entities 无法识别方法'System.Linq.IQueryable
1[SafetyPlus.Data.Models.Employee] JoinedEmployees(System.Linq.IQueryable
1[SafetyPlus.Data.TaskContact],System.Linq.Expressions.Expression1[System.Func
2[SafetyPlus.Data.TaskContact,System.Boolean]])'方法,并且此方法不能翻译成商店表达式。
有没有办法解决这个问题?在其他类似的查询中重用它会非常好。看来这应该可行。
内联版本:
public static Expression<Func<SpwTask, TaskView>> Tasks(this TaskService service)
{
return (x) => new TaskView()
{
NotifyList =
(from c in service.db.TaskContacts.
where c.TaskId == x.Id
join e in db.Employees on c.EmployeeId equals e.Id
where e.CompanyId == id
select e).Select(Projections.SimpleEmployees)
};
}
当我运行查询的代码内联版本时,我得到一个生成的单个 SQL,它经过优化,是我想要的,但不可重用。
起初,我认为下面给出的 Compile() 解决方案是我需要的答案,但在查看 SQL Profiler 时,我意识到外部任务查询的每一行都在为每个任务运行一个查询,而不是单个查询对于整个数据集。这几乎违背了重用查询的目的。
解决方案
您应该将其作为委托传递,而不在 Select 中调用它,并在使用前进行编译。
尝试这个:
db.Tasks.Select(Tasks.Compile());
推荐阅读
- django - 夹层框架博客类别对象在模板上显示
- graph-databases - 如何管理 Gentics Mesh 中节点的状态?
- php - 当我上传多个图像并循环抛出它们时,foreach 循环仅获得第一个值
- django - 我应该在全球范围内安装 virtualenvwrapper 吗?
- python-3.x - Flask 中的 init_app 函数的目的是什么?
- c - 修改函数中的数组后输出错误(在 C 中)
- node.js - 将 req.body 直接传递给 mongo db 时的安全性
- docker - Vuejs 客户端无法在 MacOS 上通过 gRPC 与 Go 后端通信
- java - 提取 Spring Boot 启动器以分离 JAR
- javascript - 寻找 Javascript / jQuery 事件触发器