LINQ to SQL : 여러 열에서 여러 조인 이게 가능해?


131

주어진:

TABLE_1다음 열로 명명 된 테이블 :

  • ID
  • ColumnA
  • ColumnB
  • ColumnC

어디 SQL 쿼리를 TABLE_1두 번 오프의 기반 자체 조인 ColumnA, ColumnB, ColumnC. 쿼리는 다음과 같습니다.

Select t1.ID, t2.ID, t3.ID
  From TABLE_1 t1
  Left Join TABLE_1 t2 On
       t1.ColumnA = t2.ColumnA
   And t1.ColumnB = t2.ColumnB
   And t1.ColumnC = t2.ColumnC
  Left Join TABLE_1 t3 On
       t2.ColumnA = t3.ColumnA
   And t2.ColumnB = t3.ColumnB
   And t2.ColumnC = t3.ColumnC
... and query continues on etc.

문제:

LINQ에서 해당 쿼리를 다시 작성해야합니다. 나는 그것을 찌르려고 노력했다.

var query =
    from t1 in myTABLE1List // List<TABLE_1>
    join t2 in myTABLE1List
      on t1.ColumnA equals t2.ColumnA
      && t1.ColumnB equals t2.ColumnA
    // ... and at this point intellisense is making it very obvious
    // I am doing something wrong :(

LINQ에서 쿼리를 작성하려면 어떻게합니까? 내가 뭘 잘못하고 있죠?

답변:


242

Linq의 여러 열을 SQL에 조인하는 것은 약간 다릅니다.

var query =
    from t1 in myTABLE1List // List<TABLE_1>
    join t2 in myTABLE1List
      on new { t1.ColumnA, t1.ColumnB } equals new { t2.ColumnA, t2.ColumnB }
    ...

익명 유형을 활용하고 비교하려는 여러 열에 대한 유형을 작성해야합니다.

이것은 처음에는 혼란스러워 보이지만 일단 SQL이 표현식에서 구성되는 방식에 익숙해지면 훨씬 더 의미가 있습니다. 커버 아래에서 원하는 조인 유형을 생성합니다.

편집 주석을 기반으로 두 번째 조인의 예를 추가합니다.

var query =
    from t1 in myTABLE1List // List<TABLE_1>
    join t2 in myTABLE1List
      on new { A = t1.ColumnA, B = t1.ColumnB } equals new { A = t2.ColumnA, B = t2.ColumnB }
    join t3 in myTABLE1List
      on new { A = t2.ColumnA, B =  t2.ColumnB } equals new { A = t3.ColumnA, B = t3.ColumnB }
    ...

4
이것은 두 조인에 효과적입니다. 세 조인과 함께 작동하려면 필요합니다. 죄송합니다. 두 번째 코드 블록은 약간 잘못된 것입니다.
aarona

46
형식 유추에 대한 컴파일러 오류가 발생하면 (1) 형식이 동일하고 (2) 열 이름이 같은 두 가지 사항을 확인하십시오. 이름 부분은 문제입니다. 이 예는 모든 열이 varchars 인 경우에도 컴파일되지 않습니다 join T2 in db.tbl2 on new { T1.firstName, T1.secondName } equals new { T2.colFirst, T2.colSecond }. 이를 변경하면 컴파일됩니다.join T2 in db.tbl2 on new { N1 = T1.firstName, N2 = T1.secondName } equals new { N1 = T2.colFirst, N2 = T2.colSecond }
user2023861

4
문제점을 명명하는 것은 새로운 콜라 = {t1.ColumnA, COLB = t1.ColumnB}에 myTABLE1List에 가입 myTABLE1List T2에서 T1로부터 의해 제거 될 수있다 새로운 콜라 = {t2.ColumnA, colBBt2.ColumnB 같음}
Baqer Naqvi

1
익명 속성에 할당해야하므로 예제를 수정 해주세요.
AceMark

1
LINQ에 문제가 있습니다. 여러 테이블에서 조인 할 수 있고 여러 필드에서 조인 할 수 있지만 예제에서 볼 수 있듯이 둘 다에서 수행 할 수는 없습니다. 따라서 1 개의 필드에 조인이 있고 그 뒤에 2 번째 조인이 있다고 가정하십시오. new {x.field}와 new {y.field}를 사용하도록 첫 번째 조인 (또는 둘 다)을 변경하면 컴파일러 오류가 발생합니다. 기능적으로는 아무것도 변경하지 않았습니다. .Net 사용하기 4.6.1.
user2415376

12

LINQ2SQL에서는 내부 조인을 사용할 때 명시 적으로 조인 할 필요가 없습니다.

데이터베이스에 적절한 외래 키 관계가있는 경우 LINQ 디자이너에서 관계를 자동으로 얻습니다 (그렇지 않으면 디자이너에서 수동으로 관계를 만들 수는 있지만 실제로 데이터베이스에 적절한 관계가 있어야 함)

부모-자녀 관계

그런 다음 "점 표기법"으로 관련 테이블에 액세스 할 수 있습니다.

var q = from child in context.Childs
        where child.Parent.col2 == 4
        select new
        {
            childCol1 = child.col1,
            parentCol1 = child.Parent.col1,
        };

쿼리를 생성합니다

SELECT [t0].[col1] AS [childCol1], [t1].[col1] AS [parentCol1]
FROM [dbo].[Child] AS [t0]
INNER JOIN [dbo].[Parent] AS [t1] ON ([t1].[col1] = [t0].[col1]) AND ([t1].[col2] = [t0].[col2])
WHERE [t1].[col2] = @p0
-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [4]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.1

내 의견으로는 이것은 훨씬 더 읽기 쉽고 실제 조인 메커니즘이 아닌 특별한 조건에 집중할 수있게합니다.

편집
이것은 물론 데이터베이스 모델과 연결하려는 경우에만 적용됩니다. 당신이 "모델 밖에"가입하려는 경우 수동에 의존 할 필요가 같이 참여 대답 에서 Quintin 님 로빈슨


11

Title_Authors는 한 번의 프로젝트 결과에 참여하고 체인을 계속하는 두 가지를 찾습니다.

        DataClasses1DataContext db = new DataClasses1DataContext();
        var queryresults = from a in db.Authors                                          
                    join ba in db.Title_Authors                           
                    on a.Au_ID equals ba.Au_ID into idAuthor
                    from c in idAuthor
                    join t in db.Titles  
                    on c.ISBN equals t.ISBN 
                    select new { Author = a.Author1,Title= t.Title1 };

        foreach (var item in queryresults)
        {
            MessageBox.Show(item.Author);
            MessageBox.Show(item.Title);
            return;
        }

10

U는 또한 사용할 수 있습니다 :

var query =
    from t1 in myTABLE1List 
    join t2 in myTABLE1List
      on new { ColA=t1.ColumnA, ColB=t1.ColumnB } equals new { ColA=t2.ColumnA, ColB=t2.ColumnB }
    join t3 in myTABLE1List
      on new {ColC=t2.ColumnA, ColD=t2.ColumnB } equals new { ColC=t3.ColumnA, ColD=t3.ColumnB }

3
아아 !! 작동합니다! 그리고 중요한 차이점은, 다른 조인에서 같은 필드가되도록 "ColA ="부분을 수행해야한다는 것입니다. 몇 년 동안 나는 그렇게하지 않았지만 여러 분야에서 1 명의 조인이 필요했습니다. 그러나 이제 더 많은 것이 필요 하며이 예제와 같이 필드에 변수 이름을 할당하면 작동합니다.
user2415376

3

여러 개의 조인이 사용되는 또 다른 예를 제공하고 싶습니다.

 DataClasses1DataContext ctx = new DataClasses1DataContext();

        var Owners = ctx.OwnerMasters;
        var Category = ctx.CategoryMasters;
        var Status = ctx.StatusMasters;
        var Tasks = ctx.TaskMasters;

        var xyz = from t in Tasks
                  join c in Category
                  on t.TaskCategory equals c.CategoryID
                  join s in Status
                  on t.TaskStatus equals s.StatusID
                  join o in Owners
                  on t.TaskOwner equals o.OwnerID
                  select new
                  {
                      t.TaskID,
                      t.TaskShortDescription,
                      c.CategoryName,
                      s.StatusName,
                      o.OwnerName
                  };

9
똑같은 것은 아닙니다. 문제는 각각의 여러 열을 기준으로 테이블을 조인하고 각각의 단일 열을 기반으로 여러 테이블을 조인하는 것입니다.
등시성

1

두 테이블에서 열 수가 동일하지 않은 경우에도 조인 할 수 있으며 정적 값을 테이블 열에 맵핑 할 수 있습니다

from t1 in Table1 
join t2 in Table2 
on new {X = t1.Column1, Y = 0 } on new {X = t2.Column1, Y = t2.Column2 }
select new {t1, t2}

-6

제 생각에는 이것이 여러 필드로 두 테이블을 조인하는 가장 간단한 방법입니다.

from a in Table1 join b in Table2    
       on (a.Field1.ToString() + "&" + a.Field2.ToString())     
       equals  (b.Field1.ToString() + "&" + b.Field2.ToString())  
     select a

SQL에서이 작업을 수행하면 각 열을 개별적으로 조인하는 것보다 속도가 상당히 느려집니다 (데이터 집합이 크지 않은 경우 여전히 빠르지 만). 아마 linq는 명백한 SQL을 생성 할 것이므로이 솔루션을 사용하면 성능을 염두에 두어야합니다.
EGP

-10

이런 식으로 쿼리를 작성할 수 있습니다.

var query = from t1 in myTABLE1List // List<TABLE_1>
            join t2 in myTABLE1List
               on t1.ColumnA equals t2.ColumnA
               and t1.ColumnB equals t2.ColumnA

열을 여러 열과 비교하려는 경우.


1
@ user658720 StackOverFlow에 오신 것을 환영합니다 :). 쉽게 읽을 수 있도록 코드를 형식화하는 것이 좋습니다. 텍스트를 선택하고 편집기에서 코드 버튼을 클릭 할 수 있습니다.
aarona
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.