如何使用LINQ选择对象?

时间:2012-07-19 05:23:35

标签: c# .net linq linq-to-entities

我的数据看起来像这样:

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对象。对于用户1Songs列表中有3个项目。对于用户2Songs列表中会有1个项目。

4 个答案:

答案 0 :(得分:37)

songs.UserSongs.GroupBy(x => x.User).Select(g => new SongsForUser() 
{ 
    User = g.Key,
    Songs = g.Select(s => s.SongId).ToList()
});

答案 1 :(得分:19)

我怀疑你想要:

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

编辑:以上是&#34;提供商中立&#34;但听起来它并没有与LINQ to Entities合作。你可以能够让它像这样工作:

var songsByUser = from song in songs.UserSongs
                  group song.SongId by song.UserId into g
                  select new SongsForUser { User = g.Key, Songs = g.ToList() };

var songsByUser = songs.UserSongs .GroupBy(song => song.UserId, song => song.SongId) .AsEnumerable() .Select(g => new SongsForUser { User = g.Key, Songs = g.ToList() }); 调用将强制在数据库中完成分组,但最终预测(包括AsEnumerable调用)将在本地完成。您应该检查生成的SQL的效率。

答案 2 :(得分: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的歌曲列表。

答案 3 :(得分: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();