C# Select 和 SelectMany 的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/958949/
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
Difference Between Select and SelectMany
提问by Tarik
I've been searching the difference between Selectand SelectManybut I haven't been able to find a suitable answer. I need to learn the difference when using LINQ To SQL but all I've found are standard array examples.
我一直在寻找 和 之间的区别Select,SelectMany但一直找不到合适的答案。我需要了解使用 LINQ To SQL 时的区别,但我发现的只是标准数组示例。
Can someone provide a LINQ To SQL example?
有人可以提供 LINQ To SQL 示例吗?
采纳答案by Mike Two
SelectManyflattens queries that return lists of lists. For example
SelectMany扁平化返回列表列表的查询。例如
public class PhoneNumber
{
public string Number { get; set; }
}
public class Person
{
public IEnumerable<PhoneNumber> PhoneNumbers { get; set; }
public string Name { get; set; }
}
IEnumerable<Person> people = new List<Person>();
// Select gets a list of lists of phone numbers
IEnumerable<IEnumerable<PhoneNumber>> phoneLists = people.Select(p => p.PhoneNumbers);
// SelectMany flattens it to just a list of phone numbers.
IEnumerable<PhoneNumber> phoneNumbers = people.SelectMany(p => p.PhoneNumbers);
// And to include data from the parent in the result:
// pass an expression to the second parameter (resultSelector) in the overload:
var directory = people
.SelectMany(p => p.PhoneNumbers,
(parent, child) => new { parent.Name, child.Number });
回答by Nathan Koop
I understand SelectManyto work like a join shortcut.
我知道SelectMany像连接快捷方式一样工作。
So you can:
这样你就可以:
var orders = customers
.Where(c => c.CustomerName == "Acme")
.SelectMany(c => c.Orders);
回答by Michael Petrotta
回答by roland
There are several overloads to SelectMany. One of them allows you to keep trace of any relationship between parent and children while traversing the hierarchy.
有几个重载到SelectMany. 其中之一允许您在遍历层次结构时跟踪父级和子级之间的任何关系。
Example: suppose you have the following structure: League -> Teams -> Player.
示例:假设您具有以下结构:League -> Teams -> Player.
You can easily return a flat collection of players. However you may lose any reference to the team the player is part of.
您可以轻松返回一组扁平化的播放器。但是,您可能会丢失对玩家所在团队的任何引用。
Fortunately there is an overload for such purpose:
幸运的是,为此目的有一个重载:
var teamsAndTheirLeagues =
from helper in leagues.SelectMany
( l => l.Teams
, ( league, team ) => new { league, team } )
where helper.team.Players.Count > 2
&& helper.league.Teams.Count < 10
select new
{ LeagueID = helper.league.ID
, Team = helper.team
};
The previous example is taken from Dan's IK blog. I strongly recommend you take a look at it.
前面的例子取自Dan 的 IK 博客。我强烈建议你看一看。
回答by Alexandr
Select is a simple one-to-one projection from source element to a result element. Select- Many is used when there are multiple from clauses in a query expression: each element in the original sequence is used to generate a new sequence.
Select 是从源元素到结果元素的简单一对一投影。Select-Many 在查询表达式中有多个 from 子句时使用:原始序列中的每个元素用于生成新序列。
回答by Sriwantha Attanayake
Select many is like cross join operation in SQLwhere it takes the cross product.
For example if we have
Select many 就像SQL中的交叉连接操作,它需要交叉乘积。
例如,如果我们有
Set A={a,b,c}
Set B={x,y}
Select many can be used to get the following set
选择多个可以用来得到下面的集合
{ (x,a) , (x,b) , (x,c) , (y,a) , (y,b) , (y,c) }
Note that here we take the all the possible combinations that can be made from the elements of set A and set B.
请注意,这里我们采用了可以由集合 A 和集合 B 的元素组成的所有可能组合。
Here is a LINQ example you can try
这是您可以尝试的 LINQ 示例
List<string> animals = new List<string>() { "cat", "dog", "donkey" };
List<int> number = new List<int>() { 10, 20 };
var mix = number.SelectMany(num => animals, (n, a) => new { n, a });
the mix will have following elements in flat structure like
混合将在平面结构中具有以下元素,例如
{(10,cat), (10,dog), (10,donkey), (20,cat), (20,dog), (20,donkey)}
回答by AlejandroR


var players = db.SoccerTeams.Where(c => c.Country == "Spain")
.SelectMany(c => c.players);
foreach(var player in players)
{
Console.WriteLine(player.LastName);
}
- De Gea
- Alba
- Costa
- Villa
- Busquets
- 德赫亚
- 阿尔巴
- 科斯塔
- 别墅
- 布斯克茨
...
...
回答by Rm558
Some SelectMany may not be necessary. Below 2 queries give the same result.
有些 SelectMany 可能不是必需的。以下 2 个查询给出相同的结果。
Customers.Where(c=>c.Name=="Tom").SelectMany(c=>c.Orders)
Orders.Where(o=>o.Customer.Name=="Tom")
For 1-to-Many relationship,
对于一对多关系,
- if Start from "1", SelectMany is needed, it flattens the many.
- if Start from "Many", SelectMany is not needed. (still be able to filter from "1", also this is simpler than below standard join query)
- 如果从“1”开始,则需要 SelectMany,它将使许多变平。
- 如果从“Many”开始,则不需要 SelectMany。(仍然可以从 "1" 过滤,这也比标准连接查询更简单)
from o in Orders
join c in Customers on o.CustomerID equals c.ID
where c.Name == "Tom"
select o
回答by user5966157
It is the best way to understand i think.
这是理解我认为的最好方法。
var query =
Enumerable
.Range(1, 10)
.SelectMany(ints => Enumerable.Range(1, 10), (a, b) => $"{a} * {b} = {a * b}")
.ToArray();
Console.WriteLine(string.Join(Environment.NewLine, query));
Console.Read();
Multiplication Table example.
乘法表示例。
回答by RickL
Without getting too technical - database with many Organizations, each with many Users:-
没有太技术性 - 具有许多组织的数据库,每个组织都有许多用户:-
var orgId = "123456789";
var userList1 = db.Organizations
.Where(a => a.OrganizationId == orgId)
.SelectMany(a => a.Users)
.ToList();
var userList2 = db.Users
.Where(a => a.OrganizationId == orgId)
.ToList();
both return the sameApplicationUser list for the selected Organization.
两者都为所选组织返回相同的ApplicationUser 列表。
The first "projects" from Organization to Users, the second queries the Users table directly.
第一个“项目”从组织到用户,第二个直接查询用户表。

