У меня есть две таблицы, с которыми я использую Linq to SQL. Таблицы имеют связь 1 ко многим. Важная часть схемы базы данных выглядит следующим образом:
Camera:
Id (int)
SerialNumber (string)
...
CameraCalibration
Id (int)
CameraFk (int)
...
Используя LINQ to SQL, я могу получить список всех калибровок камер для камер с 10-символьными серийными номерами следующим образом.
var query = from n in db.CameraCalibrations
where n.Camera.SerialNumber.Length == 10
select n
Насколько я понимаю LINQ, следующий запрос должен работать одинаково (даже если сравнивать его довольно жестоко...)
var query = from n in db.CameraCalibrations
where db.Cameras.Where(c => c.Id == n.CameraFk).SingleOrDefault()
.SerialNumber.Length == 10
select n
Однако, когда я выполняю этот второй запрос к базе данных, я получаю исключение SQL, в котором говорится: «Невозможно вызвать методы для nvarchar». Когда я смотрю на сгенерированный SQL, становится совершенно ясно, почему генерируется исключение:
SELECT t0.*
FROM CameraCalibration AS t0
WHERE (
SELECT t1.serialNumber.Length
FROM Camera AS t1
WHERE t1.id = t0.cameraFk
) = 10
Обратите внимание, как сгенерированный SQL использует выражение t1.serialNumber.Length? Я ожидал, что это будет переведено в LEN(t1.serialNumber), и действительно, с этим изменением запрос работает.
Я делаю что-то не так здесь? Или это ошибка в том, как я структурировал свой запрос и/или ограничение LINQ to SQL?
Хотя я могу легко реструктурировать запрос, который использовал для демонстрации проблемы, в моем реальном сценарии это будет намного сложнее (частично из-за задействования динамически генерируемого LINQ).
Как я могу написать запрос, аналогичный второму (с поиском, выполняемым в предложении where), который LINQ to SQL будет счастлив выполнить?