Как поставщик 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поддерживается хотя.

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