2つのテーブルがDH_MASTER
ありDH_ALIAS
ます。 DH_MASTER
名前など、人に関する情報が含まれています。 DH_ALIAS
その人に関するAKAレコードが含まれています。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クエリアナライザに貼り付け、LIKE
パラメータの周りにアポストロフィを追加すると、問題なく実行されることです。実際、200万行を超える場合でも、非常に高速です(まばたき)。
ただし、LINQクエリを実行すると、Webアプリは約31秒間ロックされてから、gv.DataBindで次のエラーが発生して最終的に失敗します。 Exception has been thrown by the target of an invocation.
このinnerExceptionで: 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