Abe*_*ler 27 .net c# linq linq-to-entities
我的数据看起来像这样:
UserId | SongId
-------- --------
1 1
1 4
1 12
2 95
Run Code Online (Sandbox Code Playgroud)
我也有以下课程:
class SongsForUser
{
public int User;
public List<int> Songs;
}
Run Code Online (Sandbox Code Playgroud)
我想做的是使用LINQ从我的数据中选择以创建SongsForUser对象的集合.以下是我到目前为止所提出的:
var userCombos = songs.UserSongs.Select(x => new SongsForUser() { User = x.UserId,
Songs = /*What goes here?*/ });
Run Code Online (Sandbox Code Playgroud)
我如何填写我的Songs清单?
所以结果应该是两个SongsForUser对象.对于用户1,它将在Songs列表中有3个项目.对于用户2,它将在Songs列表中有1个项目.
For*_*veR 38
songs.UserSongs.GroupBy(x => x.User).Select(g => new SongsForUser()
{
User = g.Key,
Songs = g.Select(s => s.SongId).ToList()
});
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 19
我怀疑你想要:
var songsByUser = songs.UserSongs
.GroupBy(song => song.UserId, song => song.SongId)
.Select(g => new SongsForUser { User = g.Key,
Songs = g.ToList() });
Run Code Online (Sandbox Code Playgroud)
为了解释,在GroupBy您将拥有一堆组之后,每个组的键是用户ID,并且组内的值是歌曲ID:
Key = 1, Values = 1, 4, 12
Key = 2, Value = 95
Run Code Online (Sandbox Code Playgroud)
然后你只是将它转换成你的SongsForUser类型.请注意,()在对象初始值设定项中调用构造函数时,不需要显式包含它 - 除非需要指定构造函数参数,否则它是隐式的.
顺便说一句,你可以在一个GroupBy电话中完成所有这些:
var songsByUser = songs.UserSongs
.GroupBy(song => song.UserId, song => song.SongId,
(user, ids) => new SongsForUser { User = user,
Songs = ids.ToList() });
Run Code Online (Sandbox Code Playgroud)
就个人而言,我通常会发现一个单独的Select调用更具可读性.
您还可以使用查询表达式完成所有这些操作:
var songsByUser = from song in songs.UserSongs
group song.SongId by song.UserId into g
select new SongsForUser { User = g.Key, Songs = g.ToList() };
Run Code Online (Sandbox Code Playgroud)
编辑:以上是"提供商中立",但听起来它不适用于LINQ to Entities.您可能能够像这样工作:
var songsByUser = songs.UserSongs
.GroupBy(song => song.UserId, song => song.SongId)
.AsEnumerable()
.Select(g => new SongsForUser { User = g.Key,
Songs = g.ToList() });
Run Code Online (Sandbox Code Playgroud)
该AsEnumerable调用将强制在数据库中完成分组,但最终投影(包括ToList调用)将在本地完成.您应该检查生成的SQL的效率.