У меня есть две таблицы, DH_MASTER
и DH_ALIAS
. DH_MASTER
содержит информацию о человеке, включая его имя. DH_ALIAS
содержит записи АКА о человеке. Таблицы связаны полем Operator
, которое является первичным ключом в DH_MASTER
.
Пользователи хотят искать по имени, хранящемуся в DH_MASTER
, а также искать по всем известным псевдонимам. Если какие-либо совпадения найдены либо в DH_MASTER
, либо DH_ALIAS
, то должна быть возвращена сущность DH_MASTER
.
Я создал запрос ниже, который должен дать результаты, которые я описал (вернуть все строки DH_MASTER
, где DH_MASTER.Name == name
или DH_MASTER.DH_ALIAs(n).Name == name
).
Работает нормально, если я использую только ОДИН из .Contains
строк. Неважно, какой я использую. Но выполнение не удается, когда я пытаюсь использовать ОБА одновременно.
qry = From m In Context.DH_MASTERs _
Where (m.Name.Contains(name)) _
OrElse ((From a In m.DH_ALIAs _
Where a.Name.Contains(name)).Count() > 0) _
Select m
Запрос LinqToSQL оценивается следующим кодом SQL (как показано в визуализаторе запросов SQL Server)
SELECT [t0].[Operator], [t0].[Name], [t0].[Version]
FROM [DHOWNER].[DH_MASTER] AS [t0]
WHERE ([t0].[Name] LIKE %smith%) OR (((
SELECT COUNT(*)
FROM [DHOWNER].[DH_ALIAS] AS [t1]
WHERE ([t1].[Name] LIKE %smith%) AND ([t1].[Operator] = [t0].[Operator])
)) > 0)
РЕДАКТИРОВАТЬ: если установить флажок «Показать оригинал» в визуализаторе запросов, откроется параметризованный запрос, как и ожидалось, поэтому этот блок текста ниже следует игнорировать.
Я не знаю, является ли это проблемой или нет, но `.Contains` оценивает выражение` LIKE` (что я и ожидаю), но параметр не заключен в апострофы.
Интересно то, что если я скопирую / вставлю SQL-запрос в SQL 2005 Query Analyzer и добавлю апострофы вокруг параметров LIKE
, он будет работать нормально. На самом деле, это молниеносно (мгновение ока) даже с более чем 2 миллионами строк.
Но когда выполняется запрос LINQ, веб-приложение блокируется примерно на 31 секунду, прежде чем оно окончательно завершается с этой ошибкой на gv.DataBind: Exception has been thrown by the target of an invocation.
С этим внутренним исключением: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
Кто-нибудь знает, почему это происходит и как можно обойти это поведение? Это сводит меня с ума, потому что сгенерированный LinqToSql SQL работает нормально в анализаторе запросов!
Обновление:
Я реорганизовал свой код на основе техник ответа. Это работает!
qry = From m In qry _
Where m.Name.Contains(name) OrElse _
m.DH_ALIAs.Any(Function(aliasRec) aliasRec.Name.Contains(name)) _
Select m