2015-01-09 3 views
2

두 테이블이 있습니다. 학생표시입니다. StudentID, Name, MarkID(Nullable) :LINQ LEFT JOIN이 NULL 값에서 작동하지 않습니다.

학생에는 다음과 같은 필드가 있습니다. 마크에는 다음과 같은 필드가 있습니다 MarkID, Mark

학생 테이블

StudentID Name MarkID 

1   Mark 1 

2   Mike NULL 

3   John NULL 

4   Paul 2 

마크 테이블

MarkID Mark 

1  80 

2  100 

왼쪽 결합은 markpaul 레코드 만 사용합니다. 내가 왼쪽 테이블의 모든 레코드를 원하는 (Student) 내 쿼리는 다음과 같습니다

var query=(from s in Students join m in Marks on s.MarkID equals m.MarkID into mar 
from subMark in mar.DefaultIfEmpty() 
Select s.Name).ToList() 

참고 : 그것은 왼쪽은 NULL 값을 포함하는 경우에만 두 개의 테이블을 조인 할 때 조인을 왼쪽으로 사용하는 예제입니다 그에서 의미 시간의 왼쪽 조인 didnot는 그 기록을 가지고 온다. 도와주세요.

+0

혼란 스럽습니다. 학생 이름을 선택하는 것이 왜 처음에 합류하는 것입니까? – mattytommo

+0

@mattytommo : 그냥 테스트 일뿐입니다. –

+0

@mattytommo : 예제 일뿐입니다. –

답변

1

문제는 우리가 null 값 기록을 삭제합니다 왼쪽 join.So에 where 절을 사용합니다.

var sampleQuery= (from f in food 
      join j in juice on f.ID equals j.ID into juiceDetails from juice in juiceDetails.DefaultIfEmpty() 
      where(!j.deleted) 
      join fr in fruit on f.ID equals fr.ID into fruitDetails from fruit in fruitDetails.DefaultIfEmpty() 
      where(!fr.deleted) 
      select new 
      { 
      // codes 

      }); 

대신이의 우리는 잘 작동이

var sampleQuery= (from f in food 
      join j in juice.Table().where(x=>!x.deleted) on f.ID equals j.ID into juiceDetails from juice in juiceDetails.DefaultIfEmpty()    
      join fr in fruit.Table().where(x=>!x.deleted) on f.ID equals fr.ID into fruitDetails from fruit in fruitDetails.DefaultIfEmpty()     
      select new 
      { 
      // codes 

      }); 

itself.Like 표에 where 절을 확인해야합니다. 감사합니다.

1

조인 할 때 Join 문에 From을 작성했습니다. 대신 당신은 in를 사용해야합니다 ::

from s in Students 
    join m in Marks on s.MarkID equals m.ID into mar 
    from subMark in mar.DefaultIfEmpty() 
    Select s.Name).ToList() 
+0

아마도 그 부분에 붙여 넣기 오류라고 생각합니다. 좋은 지점. – mattytommo

+1

@Rahul : 예, 잊어 버렸습니다. 단지 예입니다. 두 테이블을 결합 할 때 의심의 여지가 있습니다. 왼쪽 테이블이 forgein 키 필드의 Null 값을 그대로 유지하면 NULL 값이 기록에 남지 않았습니다. –

4

NULL 비교는 항상 false입니다. 이것이 SQL의 3 가지 논리가 작동하는 방식입니다. 값이 모두 null 인 행을 일치 시키려면 둘 다 null인지 확인하는 명령문을 사용해야합니다. SQL 문에서

당신은 작성합니다

on s.MarkID == m.MarkID || (s.MarkID == null && m.MarkID==null) 
+0

선생님 C에서 LINQ를 검사하는 법 # –

+0

C#에서는 값을 null과 비교합니다. 예를 들어'S.MARKID == null'. EF 또는 LINQ-to-SQL은 이것을 'IS NULL'로 변환합니다. –

+0

이것은 실제로 작동합니다. 우리 중 대부분은 SQL의 선택적 매개 변수와 관련이 있기 때문에 변환됩니다. 유일한 예는 다음과 같습니다. 예를 들어 MarkID가 int 인 경우 Intellisense는 올바른 SQL을 생성하지만 표현식이 항상 false이기 때문에 경고를 생성하고 경고를 생성합니다. "해결 방법"을 잘 모르겠습니다. – jpgrassi

2

/편집 :

ON S.MARKID=M.MARKID OR (S.MARKID IS NULL AND M.MARKID IS NULL) 

C#에서 당신은 비교 연산자와 IS NULL이 변환됩니다 LINQ 공급자 예를 사용할 수 있습니다 내 첫 번째 대답은 FULL OUTER JOIN을 사용하는 것입니다. 이것은 정상을 넘은 길이었고 아마도 잘못되었거나 완벽하게 교정되지 않았습니다.

새로운 대답은 LEFT OUTER JOIN을 사용합니다. LinqPad를 사용하여 몇 가지 샘플 데이터를 작성하여 실제 예제를 얻었습니다. LinqPad를 사용하지 않는 경우 .Dump() 메소드를 무시하십시오.

var Students = new List<Student>() { 
     new Student() {StudentId = 1, Name ="John", MarkId = 1}, 
     new Student() {StudentId = 1, Name ="Paul", MarkId = 1}, 
     new Student() {StudentId = 1, Name ="Steve", MarkId = 1}, 
     new Student() {StudentId = 1, Name ="John", MarkId = 2}, 
     new Student() {StudentId = 1, Name ="Paul", MarkId = 3}, 
     new Student() {StudentId = 1, Name ="Steve", MarkId = 1}, 
     new Student() {StudentId = 1, Name ="Paul", MarkId = 3}, 
     new Student() {StudentId = 1, Name ="John" }, 
     new Student() {StudentId = 1, Name ="Steve" }, 
     new Student() {StudentId = 1, Name ="John", MarkId = 1} 

    }; 

    var Marks = new List<Mark>() { 
     new Mark() {MarkId = 1, Value = 60}, 
     new Mark() {MarkId = 2, Value = 80}, 
     new Mark() {MarkId = 3, Value = 100} 
    }; 

    var StudentMarks = Students 
         .GroupJoin(
          Marks, 
          st => st.MarkId, 
          mk => mk.MarkId, 
          (x,y) => new { 
              StudentId = x.StudentId, 
              Name = x.Name, 
              Mark = y.Select (z => z.Value).SingleOrDefault() 
              } 
         ) 
         .Dump(); 


} 

public class Student 
{ 
    public int StudentId { get; set; } 
    public string Name { get; set; } 
    public int MarkId { get; set; } 
} 

public class Mark 
{ 
    public int MarkId { get; set; } 
    public int Value { get; set; } 
} 

출력하십시오 MarkId없이

enter image description here

당신이 CANN 내 학생 목록에서 볼 때, 거기에 2 명 학생. 그 2는 .SingleOrDefault()으로 인해 할당 된 기본값을 얻습니다.나는 이것이 당신의 문제를 해결할 것이고 당신에게 더 이상의 피델링을위한 좋은 기초를 제공 할 것이라고 생각합니다.

참조 : How do you perform a left outer join using linq extension methods

+0

감사합니다. 그것은 잘 작동합니다. 둘 다 그 테이블에있는 플래그를 삭제했습니다. 내가 ("선택 새"전에 Where 절을 사용하여) 삭제 된 플래그 조건을 확인하고 싶습니다. 그것은 전체 레코드를 가지고하지 않았다. 그것은 NULL 값을 포함하는 레코드를 건너 뜁니다. 이 문제를 해결하는 방법 ?? (가난한 영어로 죄송합니다.) –

+0

잠시만 기다려주십시오. "간단한"GroupJoin을 사용하여 해결책을 제공하기 위해 답을 수정하겠습니다. 내 대답에 만족하지도 않았다. – Marco

+0

좋아요, 업데이트 된 답변을 추가했습니다. – Marco

관련 문제