如何使用LINQ选择对象?
我的数据看起来像这样:
UserId | SongId -------- -------- 1 1 1 4 1 12 2 95
我也有以下课程:
class SongsForUser { public int User; public List Songs; }
我想要做的是使用LINQ从我的数据中选择以创建SongsForUser对象的集合。 以下是我到目前为止所提出的:
var userCombos = songs.UserSongs.Select(x => new SongsForUser() { User = x.UserId, Songs = /*What goes here?*/ });
我如何填写我的Songs
列表?
所以结果应该是两个SongsForUser对象。 对于用户1
,它将在Songs
列表中有3个项目。 对于用户2
,它将在Songs
列表中有1个项目。
songs.UserSongs.GroupBy(x => x.User).Select(g => new SongsForUser() { User = g.Key, Songs = g.Select(s => s.SongId).ToList() });
我怀疑你想要:
var songsByUser = songs.UserSongs .GroupBy(song => song.UserId, song => song.SongId) .Select(g => new SongsForUser { User = g.Key, Songs = g.ToList() });
为了解释,在GroupBy
你将拥有一堆组,其中每个组的键是用户ID,组内的值是歌曲ID:
Key = 1, Values = 1, 4, 12 Key = 2, Value = 95
然后你只是将它转换为你的SongsForUser
类型。 请注意,在对象初始值设定项中调用构造函数时,不需要显式包含()
– 除非需要指定构造函数参数,否则它是隐式的。
你可以通过以下方式在一个GroupBy
调用中执行此操作:
var songsByUser = songs.UserSongs .GroupBy(song => song.UserId, song => song.SongId, (user, ids) => new SongsForUser { User = user, Songs = ids.ToList() });
就个人而言,我通常会发现一个单独的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() };
编辑:以上是“提供商中立”,但听起来它不适用于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() });
AsEnumerable
调用将强制在数据库中完成分组,但最终投影(包括ToList
调用)将在本地完成。 您应该检查生成的SQL的效率。
让我们说你有以下内容:
public class SongsForUser { public int UserId; public List Songs; }
那么像这样的function就可以了。 该列表只是有一些数据要测试。
public void Group() { List> SongRelations = new List>(); SongRelations.Add(new Tuple(1, 1)); SongRelations.Add(new Tuple(1, 4)); SongRelations.Add(new Tuple(1, 12)); SongRelations.Add(new Tuple(2, 95)); var list = SongRelations.GroupBy(s => s.Item1) .Select(r => new SongsForUser() { UserId = r.Key, Songs = r.Select(t => t.Item2).ToList(), }); }
list
包含2个SongsForUser类型的项目。 一个用户1和一个包含1,4和12的歌曲列表,一个用户2和一个包含95的歌曲列表。