2014-02-13 43 views
1

我有兩個結果,我試圖以工會對(的LINQ to SQL /實體)LINQ到SQL UNION聲明

var ldrSet = (from ldr in Leader 
       join emp in employee 
       on ldr.ID equals emp.ID 
       where ldr.ID.Contains("123") 
    select new {ID = ldr.ID, Name = emp.firstName + " " + emp.lastName, flag = "Edit"}); 

var allEmpSet = (from emp in employee 
       where emp.ID.Contains("123") 
    select new {ID = ldr.ID, Name = emp.firstName + " " + emp.lastName, flag = "New"}); 

var results = ldrSet.Union(allEmpSet); 

當我運行此查詢我得到的是這樣的:

123喬吹編輯

123喬吹新

234珍妮·史密斯新

345李四新

我明白這是爲什麼發生的,但有什麼辦法可以進一步通過只使用ID過濾下來此ResultSet?

我想要一條記錄返回,Edit記錄勝過New記錄。所以,我只是想這樣的:

123喬吹編輯

234珍妮·史密斯新

345李四新

回答

3

在這種情況下處理事情的正確方法不是聯盟。這是使用左外連接,而不是LINQ默認的內連接。這將允許您一次選擇所有行,並設置flag如果數據匹配得當:

var results = from e in employee 
       join l in leaders on l.ID equals e.ID into ls 
       from l in ls.DefaultIfEmpty() 
       select new { 
        e.ID, 
        Name = e.firstName + e.lastName, 
        flag = (p == null ? "New" : "Edit") 
       }; 
+0

謝謝。我很欣賞左連接的示例語法。 – webdad3

2

您可以通過自己的ID使用GroupBy到組記錄,並選擇只是其中之一:

var results = ldrSet.Union(allEmpSet) 
    .GroupBy(item => item.ID, (key, items) => 
     items.OrderBy(item => item.flag) 
     .FirstOrDefault()); 

Y您可以更改OrderBy的內容以確定選擇哪些項目。

+0

從技術上講,這是正確的。但是,如果您查看數據,更好的選擇是使用左外部聯接(其語法是屁股上的一種痛苦,但是可以實現),並且在有值時將標誌設置爲「編輯」 '領導者'表和'新',當沒有。 –

+0

@JustinNiessner不夠公平。我幾乎不理會查詢的工作部分,只是將他所需要的變成了什麼。很可能他應該改變查詢本身來產生期望的結果。 – Servy

+0

@Servy - 謝謝你。你的解決方案也可以。 – webdad3