Может ли кто-нибудь объяснить мне разницу в следующих 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
быть заполненным.