Может ли кто-нибудь объяснить мне разницу в следующих 2 запросах?

Я работаю с SqlMetal (linq to sql), чтобы извлечь материал из базы данных. Тем не менее, я получаю разные результаты, используя следующий код:

var record1 = Enumerable.FirstOrDefault(_dataContext.StaticPageLangs, 
              r => r.selected_partial_url_id == partialUrlid 
                && r.selected_last_part_url_id == lastPartUrlId 
                && r.language_id == languageId);

var record2 = _dataContext.StaticPageLangs.FirstOrDefault(
              r => r.selected_partial_url_id == partialUrlid
                && r.selected_last_part_url_id == lastPartUrlId
                && r.language_id == languageId);

После того, как эта запись1 заполнена, но запись2 равна NULL, где я ожидаю, что они будут такими же.

Кто-нибудь может объяснить разницу?

Редактировать:

На sidenote:

r.selected_partial_url_id является обнуляемым int, и поэтому сравниваемое свойство имеет значение r.selected_last_part_url_id имеет тип int, и поэтому сравниваемое свойство имеет тип r.language_id, также как и сравниваемое свойство

2 ответа

Решение

Первый запрос выполняется в памяти, поскольку вы используете Enumerable.FirstOrDefault(...). Второй запрос транслируется в SQL через контекст данных и выполняется базой данных.

Вы должны проверить SQL Server Profiler, чтобы увидеть, какой фактический запрос выполняется, чтобы увидеть, в чем разница. Какие-нибудь обнуляемые столбцы в вашей базе данных, которые могут быть проблемой?

ОБНОВИТЬ

Если вы сравниваете обнуляемые свойства в выражении, которое переводится в оператор SQL, учтите, что это может пойти не так, если оба значения сравнения равны нулю. Пример:

_dataContext.StaticPageLangs
    .FirstOrDefault(r => r.selected_partial_url_id == partialUrlid)

не будет выдавать никаких записей, если partUrlid == NULL и существует запись с selected_partial_url_id == NULL. Причина: переведенный sql содержит "selected_partial_url_id == NULL", а не "selected_partial_url_id IS NULL".

Примечание: следующий ответ относится к record1 являющийся null а также record2 быть не null, что является противоположностью вопроса, но может быть полезно для других читателей с похожими сценариями.

Если бы мне пришлось угадать, по крайней мере, один из тех, == находится на stringи это вопрос чувствительности к регистру.

record1 исходит из LINQ-to-Objects, поэтому он извлекает все строки с сервера и проверяет их локально. Те == затем чувствительны к регистру (C# / .NET == на string всегда чувствителен к регистру).

record2 похоже, что он использует реализацию БД через IQueryable<>, Это означает, что он переводится на TSQL. База данных SQL-Server может быть чувствительной к регистру или нечувствительной к регистру. Я предполагаю, что вы установили его без учета регистра.

Теперь представьте, скажем, что languageId является "en-us" в C# и 'EN-US' в базе данных.

Это может привести к record1 быть null, но record2 быть заполненным.

Другие вопросы по тегам