C# 如何使用LINQ选择对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11554414/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use LINQ to select into an object?
提问by Abe Miessler
I have data that looks like so:
我有看起来像这样的数据:
UserId | SongId
-------- --------
1 1
1 4
1 12
2 95
I also have the following class:
我还有以下课程:
class SongsForUser
{
public int User;
public List<int> Songs;
}
What I would like to do is use LINQ to select from my data to create a collection of SongsForUser objects. Below is what I have come up with so far:
我想要做的是使用 LINQ 从我的数据中选择以创建 SongsForUser 对象的集合。以下是我到目前为止的想法:
var userCombos = songs.UserSongs.Select(x => new SongsForUser() { User = x.UserId,
Songs = /*What goes here?*/ });
How would I go about populating my SongsList?
我将如何填充我的Songs列表?
So the result should be two SongsForUser objects. For user 1it would have 3 items in the Songslist. For user 2it would have 1 item in the Songslist.
所以结果应该是两个 SongsForUser 对象。对于用户1,Songs列表中有 3 个项目。对于用户2,Songs列表中将有 1 个项目。
采纳答案by ForEveR
songs.UserSongs.GroupBy(x => x.User).Select(g => new SongsForUser()
{
User = g.Key,
Songs = g.Select(s => s.SongId).ToList()
});
回答by Jon Skeet
I suspect you want:
我怀疑你想要:
var songsByUser = songs.UserSongs
.GroupBy(song => song.UserId, song => song.SongId)
.Select(g => new SongsForUser { User = g.Key,
Songs = g.ToList() });
To explain, after the GroupByyou'll have a bunch of groups, where the key of each group is the user ID, and the values within the group are the song IDs:
解释一下,在之后GroupBy你会有一堆组,其中每个组的键是用户 ID,组内的值是歌曲 ID:
Key = 1, Values = 1, 4, 12
Key = 2, Value = 95
Then you're just converting that into your SongsForUsertype. Note that you don't need to explicitly include the ()when calling the constructor in an object initializer - it's implicit unless you need to specify constructor arguments.
然后你只是把它转换成你的SongsForUser类型。请注意,()在对象初始值设定项中调用构造函数时,您不需要显式包含- 除非您需要指定构造函数参数,否则它是隐式的。
You coulddo this all in one GroupBycall, by the way:
顺便说一下,您可以在一个GroupBy电话中完成这一切:
var songsByUser = songs.UserSongs
.GroupBy(song => song.UserId, song => song.SongId,
(user, ids) => new SongsForUser { User = user,
Songs = ids.ToList() });
Personally I usually find a separate Selectcall to be more readable.
就我个人而言,我通常认为单独的Select调用更具可读性。
You can also do all of this with a query expression:
您还可以使用查询表达式完成所有这些操作:
var songsByUser = from song in songs.UserSongs
group song.SongId by song.UserId into g
select new SongsForUser { User = g.Key, Songs = g.ToList() };
EDIT: The above is "provider-neutral" but it sounds like it's not working with LINQ to Entities. You maybe able to get it to work like this:
编辑:以上是“供应商中立的”,但听起来它不适用于 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() });
The AsEnumerablecall will force the grouping to be done in the database, but the final projection (including the ToListcall) to be done locally. You should check the generated SQL for efficiency though.
该AsEnumerable调用将强制在数据库中进行分组,但最终投射(包括ToList电话),以在本地完成。不过,您应该检查生成的 SQL 以提高效率。
回答by Mare Infinitus
Lets say you have the following:
假设您有以下内容:
public class SongsForUser
{
public int UserId;
public List<int> Songs;
}
Then a function like this one here will do. The list is just there to have some data to test with.
然后像这里这样的函数就可以了。该列表只是为了有一些数据进行测试。
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(),
});
}
listcontains 2 items of type SongsForUser afterwards.
One with user 1 and a list of songs containing 1, 4 and 12
and one with user 2 and a list of songs containing 95.
list之后包含 2 个 SongsForUser 类型的项目。一个是用户 1 和一个包含 1、4 和 12 的歌曲列表,一个是用户 2 和一个包含 95 的歌曲列表。
回答by pat capozzi
In its simplest form you can just:
以最简单的形式,您可以:
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();

