我正在尝试创建可过滤可重用和可读的实体框架查询的代码。我在下面的代码工作,除非我想加入两个过滤器,如在注释掉的部分中尝试的那样。有人能够就如何使这项工作给出指导和指导吗?
以下是vs2012在行
时显示的编译时错误消息//IList<Department> departments3 = context.Set<Department>().Where(isHumanResourcesDepartment || isAccountsDepartment).ToList(); is uncommented
运营商'||'不能应用于类型的操作数 'System.Func&lt; EfGenericRepositoryPoc.DataModel.Department,bool&gt;'和 'System.Func&lt; EfGenericRepositoryPoc.DataModel.Department,bool&gt;'
private static void TestCodeReadability2()
{
EmployeeDepartmentsConnection context = new EmployeeDepartmentsConnection();
IList<Department> departments = context.Set<Department>().Where(isAccountsDepartment).ToList();
IList<Department> departments2 = context.Set<Department>().Where(isHumanResourcesDepartment).ToList();
//IList<Department> departments3 = context.Set<Department>().Where(isHumanResourcesDepartment || isAccountsDepartment).ToList();
}
private static Func<Department, bool> isAccountsDepartment = d=>d.Name.ToLower().Contains("accounts");
private static Func<Department, bool> isHumanResourcesDepartment = d=>d.Name.ToLower().Contains("human resources");
答案 0 :(得分:0)
只需添加,通过使用Func,您强制EF从数据库中提取所有数据,然后在本地过滤,而不是过滤数据库。如果要对数据库进行过滤,请通过将静态方法声明更改为
将Func包装在Expression中Expression<Func<Department, bool>>
答案 1 :(得分:0)
为了使EF能够将这些查询转换为SQL并在数据库端执行需要传递Expression
个对象而不是委托的事物。创建表达式而不是委托是非常简单的:
private static Expression<Func<Department, bool>> isAccountsDepartment =
d => d.Name.ToLower().Contains("accounts");
private static Expression<Func<Department, bool>> isHumanResourcesDepartment =
d => d.Name.ToLower().Contains("human resources");
接下来,要获取其中任一项为真的项集,您可以使用Union
来获取两个查询中的任何一项。为了确保这项工作是在数据库而不是在内存中完成的,我们需要从内部查询中删除ToList
调用,以防止它们被加载到内存中:
private static void TestCodeReadability2()
{
EmployeeDepartmentsConnection context = new EmployeeDepartmentsConnection();
var accountsDepartments = context.Set<Department>().Where(isAccountsDepartment);
var hrDepartments= context.Set<Department>().Where(isHumanResourcesDepartment);
var combined = accountsDepartments.Union(HRDepartments);
}