2011-12-21 103 views
1

到目前爲止,我已經看到很多關於多個內部聯接的SO問題,但是他們都沒有解決我的問題。我一直在嘗試在兩個表上進行內部連接,並使用上一個表中的一個在第三個表上進行子查詢。Linq to Sql - 使用具有多個參數的多個內部聯接

這裏的SQL代碼:

SELECT 
//It's a lot of select fields here. Nothing really useful to solve the problem 
FROM 
    SCHEDULES 
INNER JOIN 
    STATUS 
ON 
    SCHEDULES.COMPANY    = STATUS.COMPANY   AND 
    SCHEDULES.BANK     = STATUS.BANK    AND 
    SCHEDULES.PRODUCT    = STATUS.PRODUCT   AND 
    SCHEDULES.IDSTRING    = STATUS.IDSTRING   AND 
    SCHEDULES.RECEIVER  = 'ADMILSONDAMASCENO'  AND 
    SCHEDULES.SCHEDULING < GETDATE()     AND 
    SCHEDULES.IDSTRING IN (
     SELECT DISTINCT IDSTRING FROM DEBTS_BBRASIL WHERE 
     DEBITOS_BBRASIL.COMPANY  = SCHEDULES.COMPANY  AND 
     DEBITOS_BBRASIL.BANK   = SCHEDULES.BANK   AND 
     DEBITOS_BBRASIL.PRODUCT  = SCHEDULES.PRODUCT  AND 
     DEBITOS_BBRASIL.IDSTRING  = SCHEDULES.IDSTRING  AND 
     DEBITOS_BBRASIL.STATUS   <> 2 
) 
ORDER BY SCHEDULES.SCHEDULING DESC 

,這裏是搞什麼名堂試圖與LINQ做SQL:

from sched in SCHEDULES 
    join status in STATUS 
     on new { sched.IDSTRING, sched.COMPANY, sched.BANK, sched.PRODUCT } 
     equals new { status.IDSTRING, status.COMPANY, status.BANK, status.PRODUCT } 
    into schedStats 
    from ss in schedStats 
    join debt in DEBITOS_BBRASILs 
     on new { ss.IDSTRING, ss.COMPANY, ss.BANK, ss.PRODUCT } 
     equals new { debt.IDSTRING, debt.COMPANY, debT.BANK, debt.PRODUCT } 
    where sched.RECEIVER.Equals("ADMILSONDAMASCENO") && 
         sched.SCHEDULING <= DateTime.Now && debt.STATUS != 2 
    select new ScheduledStatus 
    { 
     //Lots of properties here 
    }; 

上面的代碼,但是,產生Cross-Join那麼Inner-Join,這我積極的是重複一些結果。在SqlServer上測試第一個代碼產生了189個結果,而我的linq to sql代碼產生了546個結果。我不知道如何重現相同的SQL代碼LINQ到SQL代碼。

我已經在linqPad上測試了它,只是爲了確定。

+0

您是否嘗試過查看生成的sql查詢線索? DbContext.Log = Console.Out(其中DbContext是您的dbContext)將在調試時將生成的SQL放入您的輸出窗口。 – 2011-12-21 17:18:34

+1

由於您已經有了TSQL,爲什麼不使用表值函數?然後使用LINQ to SQL調用函數。 http://msdn.microsoft.com/en-us/library/ms191165(v=SQL.100).aspx – Dave 2011-12-21 17:34:40

+0

不知道表值函數,感謝您的顯示。但是,我不能使用它,因爲我們有嚴格的策略,不要在數據庫上放置任何邏輯。 – AdrianoRR 2011-12-22 12:37:46

回答

1

找到我的答案後,大量的'谷歌搜索'。我需要一個子查詢來在另一個表上執行搜索,而不是另一個連接。使用linq to sql方法Any做了訣竅。這裏最能幫助我的the post

而這裏的的LINQ to SQL代碼翻譯我的TSQL代碼:

from sched in SCHEDULES 
     join status in STATUS 
      on new { sched.IDSTRING, sched.COMPANY, sched.BANK, sched.PRODUCT } 
      equals new { status.IDSTRING, status.COMPANY, status.BANK, status.PRODUCT } 
     where sched.RECEIVER.Equals("ADMILSONDAMASCENO") && 
       sched.SCHEDULING <= DateTime.Now && DEBITOS_BBRASILs.Any(dbb=> 
        dbb.IDSTRING.Equals(sched.IDSTRING) 
        && dbb.COMPANY.Equals(sched.COMPANY) 
        && dbb.BANK.Equals(sched.BANK) 
        && dbb.PRODUCT.Equals(sched.PRODUCT) 
        && dbb.STATUS != 2) 
     select new ScheduledStatus 
     { 
     //Lots of properties here 
     }; 
1

當使用LINQ to SQL中明確連接通常不應該被使用。如果你建立了正確的關係,你應該有可以使用的導航屬性。有了這些,查詢將是這樣的:

from sched in SCHEDULES 
where sched.status.debt != 2; 

如果數據庫中的外鍵,導航屬性將自動通過SqlMetal.exe或由人或者設計人當你放下設計者的兩個表生成表面。這些表格之間的關係將以一條線顯示(請參閱下面的示例)。

Sample navigation properties

+0

我同意你的意見。我在一些博客上看過它。這就是所謂的關聯,對嗎?不幸的是,我工作的數據庫在這些表上沒有該關聯(通過fk)。更糟的是,我無法改變它,因爲它是一個遺留系統,取決於當前這些表的工作方式。無論如何,謝謝你的回答。 – AdrianoRR 2011-12-23 03:40:18

+0

您也可以在OR設計器中手動添加關聯,而不會影響數據庫。 – 2011-12-23 08:34:10