20 августа 2014 г.

Частая ошибка №5: Непонимание объектов, лежащих в основе выражения LINQ. Перевод.

Оглавление

LINQ отлично подходит для абстрагирования задач работы с коллекциями, будь-то объекты в памяти, таблицы базы данных или XML-документы. В идеальном мире вам не нужно было бы знать какие объекты лежат в основе. Но ошибка здесь - думать что мы живем в идеальном мире. Фактически одно и тоже выражение LINQ может вернуть различные результаты при выполнении на абсолютно одинаковых данных, если эти данные были в различных форматах.
Например, рассмотрим следующее выражение:


Что произойдет если значение одного из объектов account.Status будет равно “Active” (обратите внимание на заглавную “А”)? Если myAccounts был бы объектом DbSet (который по умолчанию не учитывает регистр), то этот элемент так же бы удовлетворял выражению where. Однако, если myAccounts был бы массивом в памяти, то этот элемент не соответствовал бы условию, а значит и весь результат отличался бы.

Но постойте-ка. Когда мы ранее говорили о сравнении строк, мы видели что оператор == выполняет порядковое сравнение строк. Так почему же в этом случает оператор == выполняет сравнение строк без учета регистра?

Ответ заключается в том, что если основные объекты в выражении LINQ ссылаются на данные SQL таблицы (в нашем случае - объект DbSet из Entity Framework), то все выражение конвертируется в выражение T-SQL. При этом операторы следуют правилам T-SQL, а не правилам C#, так что в описанном выше случае сравнение происходит без учета регистра.

В общем, хотя LINQ и является полезным и совместимым способом работы с коллекциями объектов, на самом деле вам все равно надо знать, будет ли ваше выражение конвертировано в недрах C# во что-то другое или нет, чтобы быть уверенными что поведение вашего кода будет таким, как ожидалось, при выполнении.

Комментариев нет:

Отправить комментарий