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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:16:26  来源:igfitidea点击:

Difference Between Select and SelectMany

c#linq-to-sqllinq

提问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.

我一直在寻找 和 之间的区别SelectSelectMany但一直找不到合适的答案。我需要了解使用 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 });

Live Demo on .NET Fiddle

.NET Fiddle 上的现场演示

回答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

SelectMany()lets you collapse a multidimensional sequence in a way that would otherwise require a second Select()or loop.

SelectMany()允许您以需要第二个Select()或循环的方式折叠多维序列。

More details at this blog post.

这篇博文中的更多详细信息。

回答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

enter image description here

在此处输入图片说明

var players = db.SoccerTeams.Where(c => c.Country == "Spain")
                            .SelectMany(c => c.players);

foreach(var player in players)
{
    Console.WriteLine(player.LastName);
}
  1. De Gea
  2. Alba
  3. Costa
  4. Villa
  5. Busquets
  1. 德赫亚
  2. 阿尔巴
  3. 科斯塔
  4. 别墅
  5. 布斯克茨

...

...

回答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,

对于一对多关系,

  1. if Start from "1", SelectMany is needed, it flattens the many.
  2. 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. 如果从“1”开始,则需要 SelectMany,它将使许多变平。
  2. 如果从“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.

第一个“项目”从组织到用户,第二个直接查询用户表。