1

我正在學習EF5並建立一個只顯示一些歌曲和歌手的小網站。由於一首歌可以由多個歌手演唱,而歌手會有很多歌曲,所以我的EF模型如下所示。如何查詢Linq到EF5的多對多關係

enter image description here

我想顯示在一個表及其相關歌手的歌曲均榜上有名,所以我寫了一個查詢,這是迄今爲止我有。

Dim res = context.Songs _ 
     .SelectMany(Function(song) song.Artists, Function(s, a) New With 
                   {.SongTitle = s.SongTitle, _ 
                   .ArtistName = a.ArtistName, _ 
                   .Lyrics = s.Lyrics}) 

但我得到如下結果。

enter image description here

你會看到幸運的是在表中顯示的兩倍。我不希望這種情況發生。我只想展示一次,但在藝術家專欄中加入了兩位歌手。我試圖閱讀教程和許多論壇帖子,但這些教程不會讓這個複雜。

那麼我怎麼能改變查詢返回這樣的東西?

enter image description here

回答

1

我必須寫我與C#的答案,希望你能夠把它翻譯成VB。

我會做兩個改變:

  • 首先,簡單地在這種情況下使用Select,而不是SelectMany
  • 其次,引入一個名爲ViewModel而不是匿名類型,因爲它允許您添加一個方法或自定義只讀屬性,稍後將有所幫助。

視圖模型是這樣的:

public class SongViewModel 
{ 
    public string SongTitle { get; set; } 
    public string Lyrics { get; set; } 
    public IEnumerable<string> ArtistNames { get; set; } 

    public string ArtistNamesString 
    { 
     get { return string.Join(", ", ArtistNames); } 
    } 
} 

然後你可以使用此查詢:

var res = context.Songs.Select(s => new SongViewModel 
{ 
    SongTitle = s.SongTitle, 
    Lyrics = s.Lyrics, 
    ArtistNames = s.Artists.Select(a => a.ArtistName) 
}); 

現在,列出結果,你可以使用這樣一個循環(例如與控制檯輸出):

foreach (var item in res) 
{ 
    Console.WriteLine(string.Format("{0} {1} {2}", 
     item.SongTitle, item.Lyrics, item.ArtistNamesString); 
} 

這將列出每首歌曲只有一次並且藝術家名稱顯示爲逗號分隔列表。

+0

非常感謝..這是非常有用的解釋:) – lawphotog