次のクエリをLINQに変換する方法について午後に取り組んできましたが、私はそこに到達できません。LINQを使用したサブクエリでの高度な複数の結合
declare @productId int; set @productId = 3212;
select * from InformationData data where productId = @productId and orgId = 1
and exists(
select id from (
select coalesce(id1.id, id2.id, id3.id) as id from (
select productId,attributeId from InformationData where productId = @productId group by productId,attributeId
) id
left outer join InformationData id1 on id1.productId = id.productId and id1.attributeId = id.attributeId and id1.language = 1
left outer join InformationData id2 on id2.productId = id.productId and id2.attributeId = id.attributeId and id2.language = 2
left outer join InformationData id3 on id3.productId = id.productId and id3.attributeId = id.attributeId and id3.language = 0
) row
where row.id = data.id
)
クエリの目的は、2つのフォールバック言語を使用してテーブルからデータを取得するデータは、言語1に存在しないので、もし、それが言語2に取り込まれ、そして2が存在しない場合、それはグローバルな翻訳である言語0を取得します。
私はほとんど正しいの内側のクエリを取得することができます(id1.language = 1から、私はそれは私がすべてのアイデア、に参加していますテーブルのメンバーに参加してもらうように見えることはできませんを除く?)
これは私のコード(LINQPadコード)である:
次のSQL生成(
from data in (
from d in InformationData where d.ProductId == 3212 group d by new { d.ProductId, d.AttributeId } into p select new { ProductId = p.Key.ProductId, AttributeId = p.Key.AttributeId }
)
join x1 in InformationData on new { a = data.ProductId, b = data.AttributeId } equals new { a = x1.ProductId, b = x1.AttributeId } into f1
from r1 in f1.DefaultIfEmpty()
where r1.Language == 1
join x2 in InformationData on new { a = data.ProductId, b = data.AttributeId } equals new { a = x2.ProductId, b = x2.AttributeId } into f2
from r2 in f2.DefaultIfEmpty()
where r2.Language == 2
join x3 in InformationData on new { a = data.ProductId, b = data.AttributeId } equals new { a = x3.ProductId, b = x3.AttributeId } into f3
from r3 in f3.DefaultIfEmpty()
where r3.Language == 2
select new { Id = ((int?)r1.Id) ?? ((int?)r2.Id) ?? r3.Id }
).Dump();
:
-- Region Parameters
DECLARE @p0 Int SET @p0 = 3212
DECLARE @p1 Int SET @p1 = 2
DECLARE @p2 Int SET @p2 = 2
DECLARE @p3 Int SET @p3 = 1
-- EndRegion
SELECT COALESCE([t2].[id],COALESCE([t3].[id],[t4].[id])) AS [Id]
FROM (
SELECT [t0].[productId], [t0].[attributeId]
FROM [InformationData] AS [t0]
WHERE [t0].[productId] = @p0
GROUP BY [t0].[productId], [t0].[attributeId]
) AS [t1]
LEFT OUTER JOIN [InformationData] AS [t2] ON ([t1].[productId] = [t2].[productId]) AND ([t1].[attributeId] = [t2].[attributeId])
LEFT OUTER JOIN [InformationData] AS [t3] ON ([t1].[productId] = [t3].[productId]) AND ([t1].[attributeId] = [t3].[attributeId])
LEFT OUTER JOIN [InformationData] AS [t4] ON ([t1].[productId] = [t4].[productId]) AND ([t1].[attributeId] = [t4].[attributeId])
WHERE ([t4].[language] = @p1) AND ([t3].[language] = @p2) AND ([t2].[language] = @p3)
をしかし、私は多分私はちょうどよ、クエリの残りの部分と一緒にこれを置くことができません疲れた私は私を得ることを続けるCROSS APPLYをたくさんしています。誰にも何か提案はありますか?
は、残念ながら、それは私が1からフォールバックする必要があるケースを持つことができるように、この単純ではありませんさ2→0または3→2→0となる。昇順または降順に並べ替えるには、条件に基づいてソートを作成することがありますが、私は試してみましょう。私はこれを解決する方法についてはまだ非常に興味があります。なぜなら、私はかなり複雑なアプリケーションをたくさんのクエリで翻訳しているからです。 – Runeborg
より複雑な優先順位/フォールバックシーケンスの例を追加しました。 –
良い提案、私はこれを試してみます。現在私は多くの待ち時間のためにそれをプロファイルすることはできません。 – Runeborg