2015-03-24 2 views
0

Я пытаюсь создать код, который будет фильтровать запросы фрейма объекта, которые могут быть повторно использованы и доступны для чтения. Код, который у меня ниже, за исключением случаев, когда я хочу присоединиться к двум фильтрам, как это делалось в закомментированных разделах. Кто-нибудь может дать руководство и руководство о том, как сделать эту работу?Цепочки выражения Lambda

Ниже сообщение об ошибке во время компиляции, что vs2012 отображается, когда линия

//IList<Department> departments3 = context.Set<Department>().Where(isHumanResourcesDepartment || isAccountsDepartment).ToList(); is uncommented 

оператор '||' не могут быть применены к операндам типа 'System.Func < EfGenericRepositoryPoc.DataModel.Department, BOOL>' и 'System.Func < EfGenericRepositoryPoc.DataModel.Department, BOOL>'

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

Просто добавить , используя Func, вы заставляете EF вытаскивать все данные из базы данных, а затем фильтровать локально, а не фильтровать в базе данных. Если вы хотите, чтобы фильтровать по базе данных, оберните Func в Expression путем изменения статических объявления метода для

Expression<Func<Department, bool>> 
+0

Он нужно сделать, но этого недостаточно. – Servy

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); 
} 
+2

Не лучший способ - это то, что в конце [этого] (http://blogs.msdn.com/b/meek/archive/2008/05/02/linq-to-entities-combining-predicates.aspx) статья? ИМО, таким образом, лучший вариант. –

+1

Кроме того, вы не должны использовать 'Intersect', но' Union'. Разве я не прав? –

+0

@FarhadJabiev Этот подход, безусловно, может работать; он не нуждается в этом, чтобы выполнить то, что он описал здесь. Разумеется, умение «И» или «Или» произвольных выражений является более мощным, оно просто связано с большей сложностью. – Servy

Смежные вопросы