链接Lambda表达式

时间:2015-03-24 08:26:30

标签: c# linq entity-framework linq-to-entities

我正在尝试创建可过滤可重用和可读的实体框架查询的代码。我在下面的代码工作,除非我想加入两个过滤器,如在注释掉的部分中尝试的那样。有人能够就如何使这项工作给出指导和指导吗?

以下是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");

2 个答案:

答案 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);
}