1

我正在学习 EF5 并建立一个仅显示一些歌曲和歌手的小型网站。由于一首歌可以由多个歌手演唱,并且一个歌手会有很多歌曲,所以我的 EF 模型如下。

在此处输入图像描述

我想在表格中显示所有歌曲列表及其相关歌手,所以我写了一个查询,到目前为止我有。

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

但我得到如下结果。

在此处输入图像描述

您将看到 Lucky 在表格中显示两次。我不希望这种情况发生。我只想显示一次,但在“艺术家”列中加入了两位歌手。我尝试阅读教程和许多论坛帖子,但这些教程并没有变得如此复杂。

那么我怎样才能改变查询以返回这样的东西呢?

在此处输入图像描述

4

1 回答 1

1

我必须用 C# 写我的答案,希望你能把它翻译成 VB。

我会做两个改变:

  • 首先,在这种情况下简单地使用Select而不是。SelectMany
  • 其次,引入一个命名的 ViewModel 而不是匿名类型,因为它允许您添加一个方法或自定义的只读属性,这将在以后有所帮助。

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);
}

这仅列出每首歌曲一次,并且艺术家姓名显示为逗号分隔列表。

于 2013-06-29T14:48:25.320 回答