В C # оператор &&
имеет короткое замыкание, поэтому, если первое условие возвращает false, второе условие вообще не выполняется. Из MSDN:
Оператор условного «И» (&&) выполняет логическое «И» своих булевых операндов, но только при необходимости оценивает свой второй операнд.
Оператор ||
ведет себя аналогичным образом, за исключением того, что он не оценивает свой второй аргумент, если первый возвращает true.
Я не думаю, что это полная история. Остальная часть моего поста охватывает следующие моменты:
- Вы можете регистрировать операторы SQL, используя DataContext.Log.
- Ваш запрос не должен генерировать ошибку независимо от того, в какую сторону вы ее пишете.
- Существуют различия в поведении между LINQ для объектов и LINQ для SQL.
- Ваша фильтрация может выполняться локально, а не в базе данных.
Вы можете легко просмотреть сгенерированный SQL в Visual Studio без использования профилировщика SQL. Вы можете навести указатель мыши на объект запроса LINQ to SQL, и он отобразит SQL. Или вы можете использовать DataContext.Log
для записи операторов SQL, например, так:
TextWriter textWriter = new StringWriter();
using (var dc = new UserDataContext())
{
dc.Log = textWriter;
var userList = dc.Users;
var temp = (from a in userList
where (a.Name.ToString() == "john") && (a.Name != null)
select a).ToList();
}
string log = textWriter.ToString();
Вы также можете войти в файл или даже Console.Out
:
dc.Log = Console.Out;
Делая это, вы можете видеть, что запрос выглядит примерно так, хотя у вас, вероятно, будет больше столбцов в списке выбора:
SELECT [t0].[Name]
FROM [dbo].[User] AS [t0]
WHERE ([t0].[Name] = @p0) AND ([t0].[Name] IS NOT NULL)
Другое дело, что ваш запрос не должен генерировать ошибку. Даже если a.name
равен нулю, a == "john"
все равно должен работать - он просто вернет false.
Наконец, есть разница между тем, как обычно работает C #, и тем, как работает LINQ to SQL. Вы не должны получать нулевое исключение из базы данных. Чтобы продемонстрировать это, я сделаю небольшую модификацию вашего запроса - добавив ToString
после a.Name
:
var temp = (from a in userList
where (a.Name.ToString() == "john") && (a.Name != null)
select a).ToList();
Теперь это невозможно для Linq to Objects с NullReferenceException, но он работает с LINQ to SQL без исключения. Поэтому я подозреваю, что вы загрузили все элементы из базы данных в память и выполняете локальную фильтрацию. Другими словами, может быть, у вас есть что-то вроде этого:
var userList = dc.Users.ToList();
вместо следующего, который позволил бы базе данных выполнять фильтрацию:
var userList = dc.Users;
Так что я подозреваю, что в этом вопросе есть нечто большее, чем кажется на первый взгляд. Возможно, вы можете предоставить более подробную информацию.