Как стать автором
Обновить

Комментарии 11

«необходимо выяснить, существует ли у нас тип действия с системным именем NotExistingActionType»

В такой формулировке естественнее бы выглядел запрос в виде context.ActionTypes.Any(actionType => actionType.SystemName == «NotExistingActionType»); и ошибки бы не было.
Вы совершенно правы, но во-первых, статья как раз и называется «не стреляйте себе в ногу», а во-вторых, возможно, это не лучший пример, но довольно показательный.
Кстати, такой вопрос по второму примеру — метод Linq-а «Max()» в этой ситуации упадет. А что будет у Linq2Sql?
docs.oracle.com/cd/B14117_01/server.101/b10759/functions001.htm#sthref1044
All aggregate functions except COUNT(*) and GROUPING ignore nulls. You can use the NVL function in the argument to an aggregate function to substitute a value for a null. COUNT never returns null, but returns either a number or zero. For all the remaining aggregate functions, if the data set contains no rows, or contains only rows with nulls as arguments to the aggregate function, then the function returns null.

Короче, произойдет то же самое, что и при попытке получить сумму пустого набора — вы получите null (ну или эксепшн, если вы использовали не тот generic)
Автор, возможно, имеет смысл рассказать сперва о том, что при использовании Linq2SQL или EntityFramework программист работает с методами уже не IEnumerable(T), а IQueriable(T) интерфейса, и, что даже передаваемые параметры имеют разные типы. Например,

var resultForObjects = users.Where(user => user.id < 0).Sum(user => user.balance);
var context = new LinqForHabr.DataClasses1DataContext();
var resultForLTS = context.Users.Where(user => user.Id < 0).Sum(user => user.Balance);

В первом случае буде вызван метод IEnumerable.Where и параметр будет типа Func(T, TK)
Во втором случае будет IQueriable.Where и параметр будет Expression(Func(T, TK))
То есть, при одинаковом на вид коде, вызываются методы разных интерфейсов и по сути разных сигнатур, а результат (в случае работы с БД) будет зависеть от реализации провайдера (IQueriable) и реакции конкретной БД на запрос.
Чтобы обойти эти ограничения, нужно вызвать метод AsEnumerable(T) (он определен в IEnumerable и соотв доступен в IQueriable), но, важно понимать, что все операторы после вызова этого метода (при перечислении результата) будут отрабатывать уже не в БД, а на клиенте.
IQueryable конечно
Еще поправка: методы Where находятся в классах Enumerable и Queryable, а в интерфейсах таких методов нет.
Да, безусловно, я имел ввиду методы расширения, спасибо за уточнение :)
А теперь внимание, вопрос: поведение Linq2Sql и Entity Framework в этих вопросах одинаково или нет?
Спасибо за красочную метафору в заголовке: кратко, понятно и завлекающе.
Значения выражений NULL == Something, NULL != Something и даже NULL == NULL всегда будут раны NULL или Unknown, что транслируется в False
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации