2016-06-27 3 views
2

Я играл с linq своим параметром Func (на основе сущности). Потом я узнал, что такое поведениеМножественные параметры func для LINQ - EF

var idMatchQuery = new Func<MyClass, bool>(x => x.Id == someId); 
var statusMatchQuery = new Func<MyClass, bool>(x => x.Status == someStatus); 

/// works 
var a = myClassEntity.FirstOrDefault(idMatchQuery); 

/// doesn't work 
var b = myClassEntity.FirstOrDefault(p => idMatchQuery(p) && statusMatchQuery(p)); 

/// doesn't work 
var c = myClassEntity.FirstOrDefault(p => idMatchQuery(p) && p.Status == 1); 

Он бросает UnsupportedOperationException с EF не распознает эти запросы. Я мог бы принять это намного легче, если бы ни одно из вышеперечисленных не работало. Но это меня беспокоит, когда оно работает с одним и только одним запросом Func, но не с комбинациями с другими запросами.

Я уверен, что для этого есть объяснение, но я думаю, что мои поисковые термины были слишком наивны для ответа, который я ищу.

Какое объяснение этому поведение?

+0

ли первая версия «работает», является спорным, так как он решает 'Enumerable.FirstOrDefault' вызова, а не' Queryable', так что это приведет всю таблицу в памяти перед применением FUNC, который я думаю, это не то, что вы ожидаете. –

+0

хорошо, если это случай, я сейчас даже не чувствую себя хорошо. –

ответ

4

Это вызвано тем, что EF должен перевести ваш предикат на язык TSQL. Вы можете проверить, что этот параметр метода FirstOrDefault не Func<T, bool>, а вместо Expression<Func<T, bool>>, потому что последний дает нам возможность разобрать его и перевести на TSQL. Когда вы используете два Func<T, bool> или Func<T, bool> с простым условием, EF не может перевести и разобрать его на TSQL из-за внутреннего содержимого и имеет сложность, поэтому EF сохраняет этот предикат в исходном состоянии и отправляется на сервер, как он был написан вначале, в результате - UnsupportedOperationException. Итак, для EF - синтаксический анализ первого предиката гораздо проще, чем другие два.

Заключение: это обусловлено особенностями и методологией перевода C# предикатов от Expression<Func<T,bool>> к TSQL, из-за этого иногда бывает достаточно высокой сложности.

+0

Я вижу. Звучит правильно. Позвольте мне сделать это, и я вернусь к вам. –