2014-08-27 60 views
0

我有一個查詢,在SQL Server Management Studio中會是這個樣子:失落加入時自連接在同一個字段的表

SELECT 
    distinct(r2.code) AS code 
    FROM (SELECT 
    vMatrix.type AS type, 
    vMatrix.code AS code, 
    vMatrix.id AS id 
    FROM vMatrix AS vMatrix) AS Extent1 
    INNER JOIN DE_Scratch AS Extent2 ON (Extent1.code = Extent2.Code) AND (Extent1.type = Extent2.Type) 
    INNER JOIN vMatrix as r2 ON Extent1.id = r2.id 
    WHERE (Extent2.HeaderID = 94 and r2.type = 4) 

基本上我有一個表叫vMatrix和我第一次參加吧與另一個表DE_Scratch選擇vMatrix匹配CodeTypeDE_Scratch的所有記錄。到現在爲止還挺好。然後我需要再次加入vMatrix這個結果,這次匹配id字段來選擇vMatrix中與最後一次加入的id相匹配的所有記錄,然後我只是將它過濾爲type。我一直試圖拼命地在LINQ語句中使這個工作,但它不斷失去第二個連接,基本上只返回我從第一個連接的結果(如果我刪除type篩選器 - 否則它不會返回任何內容) 。例如:

var stuff = (from r1 in ctx.vMatrices 
       join sr in ctx.DE_Scratch.Where(t => t.HeaderID == header.ID) 
       on new { c = r1.code, t = r1.type } equals new { c = sr.Code, t = sr.Type } 
       join r2 in ctx.vMatrices 
       on r1.id equals r2.id into tmp 
       from t in tmp where t.region_type == filterType 
       select t.code).Distinct().ToList(); 

與此有和沒有into條款的變化,與聯接重新排列順序等都始終給我只用一個加入一個實際的查詢。看起來它不會因爲某些未知的原因而在桌上進行自我加入。

我在這裏錯過了什麼?

我的猜測是它看着id == id部分,並決定它可以優化這個加入,但它不能。生成的SQL與我的SQL語句減去第二個連接基本相同。沒有第二個inner join,也沒有第id = id條款。我該如何強迫它不要忽視那個連接?

例如這樣的:

var stuff = (from r2 in ctx.vMatrices 
      join r1 in (from t in ctx.vMatrices 
         join sr in ctx.DE_Scratch.Where(t => t.HeaderID == header.ID) 
         on new { c = t.code, t = t.type } equals new { c = Code, t = Type } 
         select t.id) 
      on r2.id equals r1 
      select r2).ToList(); 

生成此:

SELECT 
    [Extent1].[type] AS [type], 
    [Extent1].[code] AS [code], 
    [Extent1].[id] AS [id] 
    FROM (SELECT 
    [vRegionMatrix].[type] AS [type], 
    [vRegionMatrix].[code] AS [code], 
    [vRegionMatrix].[id] AS [id] 
    FROM [dbo].[vMatrix] AS [vMatrix]) AS [Extent1] 
    INNER JOIN [dbo].[DE_Scratch] AS [Extent2] ON ([Extent1].[type] = [Extent2].[Type]) AND ([Extent1].[code] = [Extent2].[Code]) 
    WHERE ([Extent2].[HeaderID] = @p__linq__0) AND (@p__linq__0 IS NOT NULL) 

UPDATE:這是關於據我已經得到:

var regions = (from r1 in 
        (from t in ctx.vMatrices 
        join sr in ctx.DE_Scratch.Where(t => t.HeaderID == header.ID) 
        on new { c = t.code, t = t.type.Value } equals new { c = sr.Code, t = sr.Type } 
        select t.id) 
       join r2 in ctx.vMatrices.GroupBy(c => c.id) 
       on r1 equals r2.Key 
        select (int?)r2.DefaultIfEmpty().Where(l => l.type == filterType).FirstOrDefault().code).Distinct().ToList(); 

幾乎作品。問題是,在某些情況下,分組將有多個條目,所以通過使用FirstOrDefault()我失去了一些結果。我需要的是相當於SelectMany趨於平緩組的結果,但是當我試圖刪除最後一行,並與另一from...in替換它:

from f in r2.DefaultIfEmpty() 
where f.type == filterType 
select f.code).Distinct().ToList(); 

我突然失去最後再加入,與沒有結束。

回答

0

在您的第二個INNER JOIN中,您指的是您之前使用第一個INNER JOIN操作過的Extend1。你可能會嘗試類似於

SELECT 
distinct(r2.code) AS code 
FROM ((SELECT 
vMatrix.type AS type, 
vMatrix.code AS code, 
vMatrix.id AS id 
FROM vMatrix AS vMatrix) AS Extent1 
INNER JOIN DE_Scratch AS Extent2 ON (Extent1.code = Extent2.Code) 
AND (Extent1.type = Extent2.Type)) AS Extend3 
INNER JOIN vMatrix as r2 ON Extent3.id = r2.id 
WHERE (Extent2.HeaderID = 94 and r2.type = 4) 
+0

謝謝,但問題不是關於SQL *本身*,我知道如何編寫SQL,它會給我我想要的結果(請參閱第一個)。我試圖弄清楚的是如何說服LINQ to實體從linq語句*生成*(或等價的)SQL。但由於某種原因,它似乎希望忽略第二次連接。 – 2014-08-27 20:05:50