web-dev-qa-db-ja.com

LINQを使用してオブジェクトを選択する方法は?

次のようなデータがあります。

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リストを作成するにはどうすればよいですか?

したがって、結果は2つのSongsForUserオブジェクトになります。ユーザー1Songsリストには3つのアイテムがあります。ユーザー2Songsリストに1つのアイテムがあります。

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

あなたが欲しいと思う:

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型に変換します。オブジェクト初期化子でコンストラクターを呼び出すときに()を明示的に含める必要はないことに注意してください。コンストラクター引数を指定する必要がない限り、暗黙的に行われます。

couldこれをすべて1つの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で動作していないようです。 may次のように動作させることができます:

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の効率を確認する必要があります。

19
Jon Skeet

次のものがあるとしましょう:

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には、その後、SongsForUserタイプの2つのアイテムが含まれます。 1つはユーザー1、1、4、12を含む曲のリストと1つはユーザー2と95を含む曲のリストです。

1
Mare Infinitus

最も単純な形式では、次のことができます。

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();
0
pat capozzi