2013-02-19 220 views
3

使用MSDN文章"How to: Perform Left Outer Joins (C# Programming Guide)"上找到的技術,我嘗試在我的Linq代碼中創建左外連接。該文章提到使用DefaultIfEmpty方法爲了從一個組連接創建一個左外連接。基本上,它指示程序包含左側(第一個)集合的結果,即使在正確的集合中沒有結果。Linq左外連接不工作

然而,這個程序執行的方式是這樣做的,就好像外部聯接沒有被指定一樣。

在我們的數據庫中,AgentProductTraining是我們的代理商採取的一系列課程。通常情況下,您不能在CourseMaterials表中輸入Course到相應的表格中,而無需在表格中輸入相應的值。然而,偶爾會發生這種情況,所以我們希望確保我們能夠返回結果,即使在AgentProductTraining中列出,但CourseMaterials中沒有任何相應的信息。

 var training = from a in db.AgentProductTraining 
         join m in db.CourseMaterials on a.CourseCode equals m.CourseCode into apm 
         where 
          a.SymNumber == id 
          from m in apm.DefaultIfEmpty() 
          where m.EffectiveDate <= a.DateTaken 
          && ((m.TerminationDate > a.DateTaken) | (m.TerminationDate == null)) 
         select new 
            { 
             a.AgentProdTrainId, 
             a.CourseCode, 
             a.Course.CourseDescription, 
             a.Course.Partner, 
             a.DateTaken, 
             a.DateExpired, 
             a.LastChangeOperator, 
             a.LastChangeDate, 
             a.ProductCode, 
             a.Product.ProductDescription, 
             m.MaterialId, 
             m.Description, 
             a.Method 
            }; 
+0

有導航屬性'AgentProductTraining.CourseMaterials'? – 2013-02-19 20:58:07

+0

此外,標題說_left內部聯接不working_,但我認爲這是外部聯接?事實上,你的文章中沒有真正的問題陳述。 – 2013-02-19 21:10:27

+0

很好,趕快,謝謝。我不相信我們在'CourseMaterials'上有一個導航屬性 – NealR 2013-02-19 21:25:10

回答

3

的MSDN示例使用了新的變數subpet

var query = from person in people 
        join pet in pets on person equals pet.Owner into gj 
        from subpet in gj.DefaultIfEmpty() 
        select new { person.FirstName, PetName = (subpet == null ? String.Empty : subpet.Name) }; 

所以,你必須使用你自己的 「subpet」,我重寫使用submat變量代碼:

 var training = from a in db.AgentProductTraining 
         join m in db.CourseMaterials on a.CourseCode equals m.CourseCode into apm 
         where 
          a.SymNumber == id 
          from submat in apm.DefaultIfEmpty() 
          where 
          (submat.EffectiveDate <= a.DateTaken || submat.EffectiveDate == null) && 
          (submat.TerminationDate > a.DateTaken || submat.TerminationDate == null) 
         select new 
            { 
             a.AgentProdTrainId, 
             a.CourseCode, 
             a.Course.CourseDescription, 
             a.Course.Partner, 
             a.DateTaken, 
             a.DateExpired, 
             a.LastChangeOperator, 
             a.LastChangeDate, 
             a.ProductCode, 
             a.Product.ProductDescription, 
             MaterialId = (submat==null?-1:submat.MaterialId), 
             Description = (submat==null?String.Empty:submat.Description), 
             a.Method 
            }; 
+0

出於某種原因,我在'training'變量的'Results View'部分得到以下錯誤消息(不知道爲什麼,目前正在研究它)'Cast值類型'Int32'失敗,因爲物化值爲空。結果類型的泛型參數或查詢必須使用可空類型。' – NealR 2013-02-19 20:50:00

+0

我假設'submat.MaterialId'不能爲null,所以在外連接返回null的情況下,你必須設置一個默認值(當AgentProductTraining記錄沒有CourseMaterials)。在這種情況下,我將編輯代碼以設置-1。 – 2013-02-19 20:52:37

+0

對不起... VS2010不喜歡那樣。我得到消息'無效的匿名類型成員聲明。匿名類型成員必須使用成員分配,簡單名稱或成員訪問來聲明' – NealR 2013-02-19 20:56:44