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 Select
and SelectMany
but 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
SelectMany
flattens 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 SelectMany
to 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.
第一个“项目”从组织到用户,第二个直接查询用户表。