2009-10-22 76 views
3

我有兩個表。Linq加入 - 重複

1.Users表(用戶名,名稱)

2.Picture表(ID,用戶名,值isPrimary)

每個用戶可以有0到多個圖片。

我想寫一個查詢,將返回所有用戶(帶或不帶圖片)和一個照片的證件(與值isPrimary =真正的圖片)。

我寫這Linq查詢:

var v = from u in Users 
    join p in Photos on u.Username equals p.Username 
    select new 
    { 
    u.Username, 
    p.ID 
      }; 

這工作,但返回重複的用戶行。 (如果用戶有多張照片)。

我想爲每個用戶獲取一行。 這可能嗎?

回答

4

這應該完全是你想要的。

from u in Users 
let p = Photos.Where(p => p.Username == u.Username).FirstOrDefault() 
where p <> null 
select new 
{ 
    u.Username, 
    p.ID 
}; 

然而,值得注意的是,你可能會更好編寫手工優化SQL和使用db.ExecuteQuery<User>或類似的檢索對象。

+0

這個查詢對性能來說真的很差嗎? – Shar 2009-10-22 18:48:18

+0

不,不是。它應該做得很好;但是,它似乎有點不可思議。 – 2009-10-22 18:52:50

2

您可以使用分組:

from p in photos 
group p by p.username into g 
select new 
    { 
    Username = g.Key, 
    PicId = g.First().Id 
    }; 

而是首先(),你可以做一些其他的過濾...

+0

這應該與我的聯合代碼或作爲一個獨立的? 你能寫出完整的代碼PLZ嗎? – Shar 2009-10-22 18:03:07

+0

您的加入代碼沒用,因爲您只是從users表中獲取用戶名,其中圖片表*已經有*。利用這樣的情況。 – Will 2009-10-22 18:21:11

+0

我明白了。但是這個查詢不支持我選擇certian用戶。 我想先選擇幾個參數的用戶(可以說例如用戶名> 1000),然後爲每個用戶獲取一張照片。 – Shar 2009-10-22 18:25:11

1

你應該把值isPrimary在WHERE條件。另外,由於用戶可以有零圖片,您需要一個左連接。

編輯:〔實施例也是繼,(可能有筆誤)

from u in Users 
join p in (from p1 in Pictures where p1.IsPrimary select p1) on u.Username equals p.Username into pp 
from p in pp.DefaultIfEmpty() 
select new 
{ 
    u.UserName, 
    PicturePath = p == null ? "DummyPath" : p.PicturePath 
} 

編輯:順便說一句,約翰Gietzen答案似乎不給你問的答案。

+0

有沒有可能給我一個例子? PLZ。 – Shar 2009-10-22 18:08:02

0

 
var upic = from u in users 
      join p in pictures on u.UserName equals p.UserName into g 
      from o in g.DefaultIfEmpty() 
      where o == null || o.IsPrimary == true 
     select new { UserName = u.UserName, Id = (o == null ? "(No picture)" : o.Id) };