我有两张桌子,DH_MASTER
和DH_ALIAS
。 DH_MASTER
包含有关人员的信息,包括他们的姓名。 DH_ALIAS
包含有关此人的 AKA 记录。这些表由Operator
作为主键的字段链接DH_MASTER
。
用户希望通过存储在其中的名称进行搜索,DH_MASTER
并通过他们所有已知的别名进行搜索。如果在其中一个中找到任何匹配项,DH_MASTER
则应返回DH_ALIAS
该实体。DH_MASTER
我创建了下面的查询,它应该给出我描述的结果(返回orDH_MASTER
的任何行)。DH_MASTER.Name == name
DH_MASTER.DH_ALIAs(n).Name == name
如果我只使用其中.Contains
一条线,它就可以正常工作。我使用哪一个并不重要。但是当我尝试同时使用 BOTH 时执行失败。
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 查询分析器中并在LIKE
参数周围添加撇号,它运行得很好。事实上,即使有超过 200 万行,它也快如闪电(眨眼间)。
但是当 LINQ 查询运行时,Web 应用程序锁定了大约 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