Как поставщик LINQ может преобразовать произвольный код?
Я понимаю, что поставщик LINQ - это "вещь", которая преобразует фактический запрос LINQ в запрос SQL (или любой другой). Это делается путем обхода AST запроса LINQ и обработки соответствующего запроса SQL. Все идет нормально.
Теперь я могу представить, что это работает для простого кода C#, такого как
where person.Age >= 18
который может быть (в основном напрямую) переведен в SQL. Но что, если я предоставлю произвольный сложный код C#, такой как:
where person.Name.StartsWith(person.Age < 25 ? 'X' : 'Y')
В SQL нет эквивалента этому, так что же делает поставщик LINQ в таком случае?
2 ответа
В SQL нет эквивалента этому
Не уверен, как он будет на самом деле писать SQL (вы можете проверить его), но это может быть просто:
where person.Name like (case when person.Age < 25 then 'X' else 'Y' end) + '%'
Чтобы получить реальный SQL (при условии, что он работает): профилируйте соединение.
Но действительно; не все вещи возможны, и часто он просто выдает исключение, чтобы указать, что он что-то не распознает или не может создать SQL. Например, если вы делаете:
where person.Name.StartsWith(MyCustomMethod(person) ? 'X' : 'Y')
тогда я ожидал бы, что это потерпит неудачу.
Тернарный оператор не слишком шумно рендерится, используя CASE
выражение.
CASE WHEN Person < 25 THEN 'X' ELSE 'Y' END
В противном случае вы получите исключение, любезно дающее указание не использовать вызовы методов в запросах Linq To SQL. я думаю что StartsWith
поддерживается хотя.