使用两个Contains语句LINQ to SQL查询失败

时间:2009-01-15 19:28:11

标签: sql linq-to-sql timeout contains

我有两个表,DH_MASTERDH_ALIASDH_MASTER包含有关某人的信息,包括他们的姓名。 DH_ALIAS包含有关此人的AKA记录。这些表格由Operator字段链接,DH_MASTER字段是DH_MASTER中的主键。

用户希望按DH_MASTER中存储的名称进行搜索,并搜索所有已知的别名。如果在DH_ALIASDH_MASTER中找到任何匹配项,则应返回DH_MASTER实体。

我创建了下面的查询,该查询应该给出我描述的结果(返回DH_MASTER.Name == nameDH_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 行中的一行,它可以正常工作。我使用哪一个并不重要。但是当我尝试同时使用BOTH时执行失败。


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)

LinqToSQL查询求值为以下SQL代码(如SQL Server Query Visualizer中所示)

LIKE

编辑:检查Query Visualizer中的“显示原始”框会按预期显示参数化查询,因此应忽略此下面的文本块。

我不知道这是否是一个问题,但`.Contains`评估为一个`LIKE`表达式(这是我期望发生的),但参数没有封装在撇号中。

有趣的是,如果我将SQL Query复制/粘贴到SQL 2005查询分析器中并在Exception has been thrown by the target of an invocation.参数周围添加撇号,它运行得很好。事实上,即使行数超过200万,它也很快(眨眼间)。

但是当LINQ查询运行时,web应用程序会锁定大约31秒,然后才会在gv.DataBind上出现此错误:Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

使用此内部异常:qry = From m In qry _ Where m.Name.Contains(name) OrElse _ m.DH_ALIAs.Any(Function(aliasRec) aliasRec.Name.Contains(name)) _ Select m

有谁知道为什么会发生这种情况以及如何处理这种行为?它让我疯狂,因为LinqToSql生成的SQL在查询分析器中运行良好!

更新

我根据答案中的技术重构了我的代码。这有效!

{{1}}

2 个答案:

答案 0 :(得分:4)

这可能不合适,因为你的问题不同,但我记得我的一个程序中有一个问题:Contains()不起作用(在我的情况下,它会在评估时抛出异常),所以也许包含 - 方法有点破碎。

我替换了

result.Contains( x )

result.Any( p => p == x )

确实有效。

你能尝试一下吗?至少它可能是朝着正确方向迈出的一步。

答案 1 :(得分:0)

Linq to sql没有直接指定值到查询中,它使用参数。你确定它直接在sql中包含了参数值吗?

无论如何,超时可能是由死锁引起的:查询想要读取表中的一行,该行被另一个(插入/更新)查询/事务锁定,并且该查询显然需要更长的时间才能完成。