2011-03-04 3 views
1

세 개의 도메인 개체가 있습니다.이 Linq 쿼리에 대한 도움말 (다 대다 합류)

Child, Classroom 및 ChildClassroom.

var childrens = new List<Child>() { 
    new Child() { ChildId = 1, FirstName = "Chris" }, 
    new Child() { ChildId = 2, FirstName = "Jenny" }, 
    new Child() { ChildId = 3, FirstName = "Dave" }, 
}; 

var classrooms = new List<Classroom>() { 
    new Classroom() { ClassroomId = 1, FullName = "Kindergarten" }, 
    new Classroom() { ClassroomId = 2, FullName = "Elementary" }, 
    new Classroom() { ClassroomId = 3, FullName = "Secondary" }, 
}; 

var childclassrooms = new List<ChildClassroom>() { 
    new ChildClassroom() { ClassroomId = 1, ChildId = 1 }, 
    new ChildClassroom() { ClassroomId = 2, ChildId = 1 }, 
    new ChildClassroom() { ClassroomId = 3, ChildId = 2 }, 
}; 

내가 원하는입니다 : 다음은 각 목록은

Linq에 이것에 대해 갈 수있는 방법은 무엇
var childClassroomRelationships = new object[] { 
    new { 
     childid = 1, 
     classrooms = new object[] { 
      new { classroomId = 1, occupied = true }, 
      new { classroomId = 2, occupied = true }, 
      new { classroomId = 3, occupied = false } 
    }, 
    ... 
}; 

?

+10

내가 더 잘 포맷으로 시작 했죠. –

+1

타입 유추 ('new [] {...}')를 사용하지 않고 배열을 만들면 익명 타입의 멤버 인'childClassroomRelationships [0] .childid'에 접근 할 수 있습니다. 'new object []'로 만들면 익명의 타입으로는 마법을 쓰지 않고도 많은 일을 할 수 없습니다. –

+0

@ Yuriy- 완료. 이제 당신은 대답 할 수 있어야합니다. –

답변

2
var kidsInClass = (
    from kid in childrens 
    from c in classrooms 
    select new { 
     ChildID = kid.ChildId, 
     classrooms = (
      from cc in childclassrooms 
      select new { 
       ClassroomID = c.ClassroomId, 
       Occupied = cc.ChildId == kid.ChildId 
      }).ToArray() 
    }).ToArray(); 
+1

@casperOne 형식 편집이 필요하다고 생각하지 않습니다. –

+0

@Yuriy :이 질문에 대한 귀하의 모든 도움에 감사드립니다. –

+0

@Chris 언제든지. –

3

이 작업을 수행 할 수 있습니다 : 그것은 있다면

여기에 매우 중요 여기에 사용할 수 없습니다한다 조인 무엇
var childClassroomRelationships = (
    from child in children 
    select { 
     childid = child.ChildId, 
     classrooms = (
      from classroom in classrooms 
      select new { 
       classroomId = classroom.ClassroomId, 
       occupied = childclassrooms.Any(
        cc => cc.ChildId == child.ChildId), 
      // Since you wanted an array. 
      }).ToArray() 
    // Since you wanted an array. 
    }).ToArray(); 

, 당신은 내부가 원인이되는 의미를 가입 얻을 것없는 아이들 어떤 교실에서 나타나지 않아야합니다 (어떤 사람이 이 아니란 것 같습니다.).

ToArray에 대한 호출로 인해 모든 시퀀스가 ​​구체화됩니다.

또한 비효율적 인 점은 점유를 확인하기 위해서 항상 매번 childclassroms 시퀀스를 반복해야한다는 것입니다.

이 "색인"과 같이 효율적인 검색을 위해 childclassrooms지도에 의해 개선 될 수

:

IDictionary<int, HashSet<int>> classroommap = (
    from mapping in childclassrooms 
    group mapping.ClassroomId by mapping.ChildId into g 
    select g).ToDictionary(g => g.Key, g => new HashSet<int>(g)); 

이 당신에게 당신이 알고 한 번에 아이를 찾아 볼 수 HashSet<int> 인스턴스의지도를 줄 것이다 교실. 그것으로, 첫 번째 쿼리가된다 :

var childClassroomRelationships = (
    from child in children 
    select { 
     childid = child.ChildId, 
     classrooms = (
      from classroom in classrooms 
      select new { 
       classroomId = classroom.ClassroomId, 
       occupied = classroommap.ContainsKey(child.ChildId) && 
        classroommap[child.ChildId]. 
         Contains(classroom.ClassroomId), 
      // Since you wanted an array. 
      }).ToArray() 
    // Since you wanted an array. 
    }).ToArray();