it-swarm-ko.com

Select와 SelectMany의 차이점

나는 SelectSelectMany의 차이점을 조사해 왔지만 적절한 답을 찾을 수 없었습니다. LINQ To SQL을 사용할 때 차이점을 알아야하지만 표준 배열 예제 만 있으면됩니다.

누군가가 LINQ To SQL 예제를 제공 할 수 있습니까?

919
Tarik

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 });

.NET상의 라이브 데모 Fiddle

1437
Mike Two

많은 것은 cross product를 취하는 SQL에서 교차 결합 연산 과 같다.
예를 들어 우리가

Set A={a,b,c}
Set B={x,y}

많은 것을 선택하면 다음과 같은 세트를 얻을 수 있습니다

{ (x,a) , (x,b) , (x,c) , (y,a) , (y,b) , (y,c) }

여기에서 우리는 집합 A의 요소와 집합 B의 모든 가능한 조합을 취합니다.

시도해 볼 수있는 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 });

믹스에는 다음과 같은 평면 구조의 요소가 있습니다.

{(10,cat), (10,dog), (10,donkey), (20,cat), (20,dog), (20,donkey)}
162

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. 드 게아
  2. 알바
  3. 코스타
  4. 별장
  5. 부스 케

...

102
AlejandroR

SelectMany()을 사용하면 다차원 Select() 또는 루프가 필요한 방식으로 다차원 시퀀스를 축소 할 수 있습니다.

자세한 내용은 블로그 게시물 .

73
Michael Petrotta

SelectMany에는 여러 가지 오버로드가 있습니다. 그 중 하나를 사용하면 계층 구조를 탐색하는 동안 부모와 자식 간의 관계를 추적 할 수 있습니다.

: 다음과 같은 구조를 가지고 있다고 가정합니다 : League -> Teams -> Player.

당신은 쉽게 플레이어의 평면 컬렉션을 반환 할 수 있습니다. 그러나 플레이어가 속한 팀에 대한 언급을 잃을 수도 있습니다.

다행히도 이러한 목적을 위해 과부하가 있습니다.

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 
                                   };

이전 예는 Dan 's IK blog 에서 가져온 것입니다. 나는 당신이 그것을 보길 강력히 권한다.

33
roland

조인 바로 가기처럼 작동하려면 SelectMany를 이해합니다.

그래서 당신은 할 수 있습니다 :

var orders = customers
             .Where(c => c.CustomerName == "Acme")
             .SelectMany(c => c.Orders);
19
Nathan Koop

Select는 소스 요소에서 결과 요소로의 간단한 1 대 1 투영입니다. Select- Many는 쿼리 식에 from 절이 여러 개있는 경우에 사용됩니다. 원본 시퀀스의 각 요소는 새 시퀀스를 생성하는 데 사용됩니다.

12
Alexandr

일부 SelectMany는 필요하지 않을 수도 있습니다. 아래 2 개의 쿼리는 동일한 결과를 제공합니다.

Customers.Where(c=>c.Name=="Tom").SelectMany(c=>c.Orders)

Orders.Where(o=>o.Customer.Name=="Tom")

1 대 다수 관계의 경우,

  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
7
Rm558

많은 사용자가있는 많은 조직과 함께 너무 기술적 인 데이터베이스가 필요하지 않습니다.

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();

둘 다 _ 선택한 Organization에 대한 동일한 ApplicationUser 목록을 반환합니다.

조직에서 사용자로의 첫 번째 "프로젝트", 두 번째 쿼리는 사용자 테이블을 직접 쿼리합니다.

4
RickL

기능적 프로그래머를 돕는 다른보기를 위해서 :

  • Selectmap입니다.
  • SelectManybind입니다 (또는 스칼라/코 틀린 사람들에게는 flatMap 임).
2
Matt Klein

쿼리가 문자열 (char 배열)을 반환하면 더 명확합니다.

예를 들어, 'Fruits'목록에 'Apple'

'Select'는 문자열을 반환합니다 :

Fruits.Select(s=>s) 

[0]: "Apple"

'SelectMany'는 문자열을 평평하게합니다 :

Fruits.SelectMany(s=>s)

[0]: 97  'a'
[1]: 112 'p'
[2]: 112 'p'
[3]: 108 'l'
[4]: 101 'e'
2
Eric Bole-Feysot

하위 배열 객체 데이터를 누적하기 위해 SelectMany + Select를 사용하는 방법에 대한 한 가지 예입니다.

전화가 걸린 사용자가 있다고 가정 해 보겠습니다.

class Phone { 
    public string BasePart = "555-xxx-xxx"; 
}

class User { 
    public string Name = "Xxxxx";
    public List<Phone> Phones; 
}

이제 모든 전화기의 모든 사용자의 BasePart를 선택해야합니다.

var usersArray = new List<User>(); // array of arrays
List<string> allBaseParts = usersArray.SelectMany(ua => ua.Phones).Select(p => p.BasePart).ToList();
0
KEMBL