30

我有看起来像这样的数据:

UserId   |  SongId
--------   --------
1          1
1          4
1          12
2          95

我也有以下课程:

class SongsForUser
{
    public int User;
    public List<int> Songs;
}

我想做的是使用 LINQ 从我的数据中进行选择以创建 SongsForUser 对象的集合。以下是我到目前为止提出的内容:

var userCombos = songs.UserSongs.Select(x => new SongsForUser() { User = x.UserId, 
                                                                  Songs = /*What goes here?*/ });

我将如何填充我的Songs列表?

所以结果应该是两个 SongsForUser 对象。对于用户1,列表中有 3 个项目Songs。对于用户2,列表中将有 1 个项目Songs

4

4 回答 4

45
songs.UserSongs.GroupBy(x => x.User).Select(g => new SongsForUser() 
{ 
    User = g.Key,
    Songs = g.Select(s => s.SongId).ToList()
});
于 2012-07-19T05:28:39.627 回答
20

我怀疑你想要:

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 的效率。

于 2012-07-19T05:30:11.467 回答
1

假设您有以下内容:

public class SongsForUser
{
    public int UserId;
    public List<int> Songs;
}

然后像这里这样的功能就可以了。该列表只是为了有一些数据进行测试。

    public void Group()
    {
        List<Tuple<int, int>> SongRelations = new List<Tuple<int, int>>();

        SongRelations.Add(new Tuple<int, int>(1, 1));
        SongRelations.Add(new Tuple<int, int>(1, 4));
        SongRelations.Add(new Tuple<int, int>(1, 12));
        SongRelations.Add(new Tuple<int, int>(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 的歌曲列表。

于 2012-07-19T05:35:42.360 回答
0

以最简单的形式,您可以:

List<MapPoint> points = db.PropertyResearches.Where(a => a.deptId == 66).Select(x => new MapPoint { property = x.notes.Substring(0, 10), latitude = x.lat, longitude = x.@long }).ToList();
于 2019-02-05T00:09:24.550 回答