从内部搜索列表

List search from within

提问人:FirstByte 提问时间:8/17/2021 最后编辑:JamiecFirstByte 更新时间:8/18/2021 访问量:68

问:

我有一个对象,它有一个其他对象的列表,它有一个另一个对象的列表。我最喜欢的例子:

public class Artist
{
    int ArtistID;
    string ArtistName;
    List<Album> Albums;
}
public class Album
{
    int AlbumID;
    string AlbumName
    List<Song> Songs
}
public class Song
{
    int SongID;
    string SongName;
}

由于一首歌可以被许多艺术家翻唱,我想搜索所有录制特定歌曲的艺术家。我知道这可以使用迭代来完成,但我确信有办法在单个语句中做到这一点。

List<Artist> list= 所有演唱《Yesterday》的艺人

谢谢。

C# 嵌套列表

评论


答:

4赞 Jamiec 8/17/2021 #1

假设您正在寻找的被调用列表Artistartists

var yesterdaySingers = artists.Where(
       art => art.Albums.Any(
               alb => alb.Songs.Any(song => song.SongName == "Yesterday")
       )
).ToList();

请注意,您必须添加才能使用上述内容。using System.Linq;

4赞 Igor 8/17/2021 #2

您可以使用 lambda 语句来实现此目的。

var artists = artistList
   .Where(art => art.Albums.Any(alb => alb.Songs.Any(song => song.SongName == "Yesterday")))
   .ToList();

评论

1赞 Jamiec 8/17/2021
明!甚至相同的变量名称(几乎)。伟大的头脑!
1赞 Igor 8/17/2021
@Jamiec - 这太不可思议了,请投赞成票:)你打败了我 20 秒。
1赞 Christopher 8/18/2021 #3

我担心您的数据/类结构本身就有缺陷。

由于一首歌可以被许多艺术家翻唱,我想搜索所有录制特定歌曲的艺术家。我知道这可以使用迭代来完成,但我确信有办法在单个语句中做到这一点。

“每个艺术家可以有多首歌,每首歌可以有多首歌”,听起来像是多对多关系的书范例。但是,您拥有的是两层 1:N。

您应该使用连接表更改它,以便 Song 和 Artist 处于正确的 N:M 关系中。

评论

0赞 Nick Daria 8/18/2021
如果不同的歌曲使用相同的主键,我不认为有什么固有的“错误”,因为上面的答案会按预期工作,但你是对的,使用连接表是首选。特别是使用 EFCore,它就像添加一些 .WithMany() 方法添加到 DbContext 配置中。