2014-11-25 1 views
1

나 자신 LINQ이 패턴을 많이 사용 찾을 수 :이 LINQ의 메서드 구문은 무엇입니까? 조인입니까? 그렇지 않으면 무엇입니까?

class Thing 
    { 
     public int ID { get; set; } 
     public int ColorID { get; set; } 
    } 
    class Color 
    { 
     public int ID { get; set; } 
     public string Description { get; set; } 
    } 
    static void Main() 
    { 
     var things = new List<Thing> { new Thing { ID = 1, ColorID = 1 }, new Thing { ID = 2, ColorID = 1 }, new Thing { ID = 3, ColorID = 2 }, new Thing { ID = 4, ColorID = 1 } }; 
     var colors = new List<Color> { new Color { ID = 1, Description = "red" }, new Color { ID = 2, Description = "green" }, new Color { ID = 3, Description = "blue" } }; 
     var joined = (from thing in things 
         from color in colors 
         where thing.ColorID == color.ID 
         select new { ID = thing.ID, Color = color.Description }).ToArray(); 
     foreach (var thing in joined) 
     { 
      Console.WriteLine("(" + thing.ID + ", " + thing.Color + ")"); 
     } 
     //Writes: 
     //(1, red) 
     //(2, red) 
     //(3, green 
     //(4, red) 
    } 

그것의 핵심은, 쿼리 구문의 네 줄은 매우 INNER JOIN 같은 내가 TSQL 쓸 수 있다고 생각하지만 난 examples of LINQ query syntax for joins 볼 때 위의 LINQ는 그렇지 않지만 join이라는 단어를 사용하십시오.

위의 LINQ가 수행하는 '조인'은 무엇이고 LINQ 메서드 구문으로 어떻게 다시 작성합니까?

답변

3

LINQ 이해 측면에서 조인을 전혀 수행하지 않습니다. 하나의 범위 변수에서 하나의 이 발생하고 두 번째 속성에서 이 발생하면 다른 하나는 이되고 다른 하나는이됩니다.

var joined = things.SelectMany(thing => colors, 
           (thing, color) => new { thing, color }) 
        .Where(pair => pair.thing.ColorID == pair.color.ID) 
        .Select(pair => new { ID = pair.thing.ID, 
             Color = pair.color.Description }) 
        .ToArray(); 

여기 pair 효과적으로 자동으로 투명 식별자으로 컴파일러에 의해 도입 : 같은 방법 구문에서이 쓰기 것입니다. 이것은 where의 필터링 때문이 아니라 from 절이 여러 개 있기 때문에 ... from 절 뒤에는 모두 SelectMany이 사용되며 투명 식별자가있어 여러 범위 변수 (thingcolor)를 참조 할 수 있습니다.)는 별도의 객체로 구성되어 파이프 라인의 각 단계에서만 개념적으로 하나의 값을 처리합니다. 두 from 절을 가지고 있음을

참고 :

from person in people 
from book in books 

... 데카르트와 같은 그 행위 가입 ...하지만 LINQ는 같은 미묘한 뭔가를 할 수 있습니다 :

from person in people 
from book in person.Books 

즉, 두 번째 시퀀스는 첫 번째 시퀀스의 "현재"값에 의존 할 수 있습니다. 파이프 라인의 모든 후속 스테이지 (예 : where 또는 select)는 첫 번째 시퀀스에서 하나, 첫 번째 시퀀스에서 요소에서 생성 된 두 번째 시퀀스에서 하나씩 각 쌍에서 작동합니다.

+0

감사합니다. 전 LINQ 독점적으로 쿼리 구문을 작성하여 시작했지만 최근에 나는 그것이 더 명확하고 더 많은 C#을 같은 방법 구문으로 스와핑했지만,이 경우에는 무슨 일이 일어나는지 설명하는 데 도움이되지만 훨씬 덜 간단합니다. – dumbledad

+0

나는 내부 루프 조인을 수행한다고 답변하려고했다. 구문은 SQL-89에서 내부 조인을 작성하는 방법과 매우 비슷합니다. 하지만 당신은 그렇지 않다고 말합니다. – Magnus

+0

@Magnus : LINQ to SQL에 의해 "내부 루프 조인"으로 변환 될 수 있습니다. 물론 ... –

관련 문제