提问人:FirstByte 提问时间:8/17/2021 最后编辑:JamiecFirstByte 更新时间:8/18/2021 访问量:68
从内部搜索列表
List search from within
问:
我有一个对象,它有一个其他对象的列表,它有一个另一个对象的列表。我最喜欢的例子:
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》的艺人
谢谢。
答:
4赞
Jamiec
8/17/2021
#1
假设您正在寻找的被调用列表Artist
artists
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 配置中。
评论