2011-09-12 3 views
3

나는 회의실에 대한 간단한 예약 시스템을 연구 중이다.Linq 그룹화 질문

Date  Room A Room B Room C Room D Room E Room F 
01/01/2011 2  5  3  2  1  5 
02/01/2011 3  5  2  5  2  2 
03/01/2011 2  5  2  4  5  8 
04/01/2011 4  7  3  5  2  2 

I : 같은 분류 데이터로

01/01/2011 1 Room A 2 
01/01/2011 2 Room B 5 
01/01/2011 3 Room C 3 
01/01/2011 4 Room D 2 
01/01/2011 5 Room E 1 
01/01/2011 6 Room F 5 
02/01/2011 1 Room A 3 
02/01/2011 2 Room B 5 
02/01/2011 3 Room C 2 
02/01/2011 4 Room D 5 
02/01/2011 5 Room E 2 
02/01/2011 6 Room F 2 
03/01/2011 1 Room A 2 
03/01/2011 2 Room B 5 
03/01/2011 3 Room C 2 

: 각 회의실은 그것의 크기에 따라 객실 유형을 할당 등 나는 다음에서 예약 객실의 수를 모양을 찾고 있어요 '이전에 데이터 집합을 사용하여이 작업을 수행했지만이 작업을 Linq를 사용하여이 프로젝트에서 수행 할 수 있어야합니다.

누군가 가장 좋은 방법을 조언 할 수 있습니까?

감사

답변

0

이 이러한 유형의 문제에 직면 할 때 내가 무슨 짓을했는지 있습니다 :

var rooms = bookings 
    .Select(b => b.Room) 
    .Distinct() 
    .OrderBy(r => r) 
    .ToArray(); 

var query = (
    from b in bookings 
    group b by b.Date into gbs 
    let l = gbs.ToLookup(gb => gb.Room, gb => gb.Count) 
    select new 
    { 
     Date = gbs.Key, 
     RoomCounts = rooms.Select(r => l[r].Sum()).ToArray(), 
    }).ToArray(); 

이 기본적으로 다음과 같은 배열을 생성합니다

var rooms = new [] 
{ 
    "Room A", "Room B", "Room C", "Room D", "Room E", "Room F", 
}; 

var query = new [] 
{ 
    new 
    { 
     Date = new DateTime(2011, 01, 01), 
     RoomCounts = new [] { 2, 5, 3, 2, 1, 5 } 
    }, 
    new 
    { 
     Date = new DateTime(2011, 01, 02), 
     RoomCounts = new [] { 3, 5, 2, 5, 2, 2 } 
    }, 
    new 
    { 
     Date = new DateTime(2011, 01, 03), 
     RoomCounts = new [] { 2, 5, 2, 0, 0, 0 } 
    }, 
}; 

RoomCounts 배열은 모두 rooms 배열과 동일한 길이이고 각 인덱스 위치의 값은 rooms 배열의 방과 일치합니다.

일반적으로 상당히 효과적입니다.

대신 스프레드 시트와 같이 그리드를 나타내는 배열 배열을 만드는 방법이 있습니다.

Func<object, IEnumerable, object[]> prepend = (o, os) => 
    (new object[] { o }).Concat(os.Cast<object>()).ToArray(); 

Func<object[], IEnumerable<object[]>, object[][]> prepends = (o, os) => 
    (new object[][] { o }).Concat(os).ToArray(); 

var query2 = prepends(prepend("Date", rooms), 
    from b in bookings 
    group b by b.Date into gbs 
    let l = gbs.ToLookup(gb => gb.Room, gb => gb.Count) 
    select prepend(gbs.Key, rooms.Select(r => l[r].Sum()))); 

의이 양식을 :

var q2 = new object[] 
    { 
     new object[] { 
      "Date", "Room A", "Room B", "Room C", "Room D", "Room E", "Room F" }, 
     new object[] { new DateTime(2011, 01, 01), 2, 5, 3, 2, 1, 5 }, 
     new object[] { new DateTime(2011, 01, 02), 3, 5, 2, 5, 2, 2 }, 
     new object[] { new DateTime(2011, 01, 03), 2, 5, 2, 0, 0, 0 }, 
    }; 

쿼리가 약간 털이 보이는 경우 대안에 대한 대안은,이 작업을 수행하는 것입니다

var query2 = (new object[] 
    { 
     (new object[] { "Date" }) 
      .Concat(rooms.Cast<object>()) 
      .ToArray() 
    }).Concat(
     from b in bookings 
     group b by b.Date into gbs 
     let l = gbs.ToLookup(gb => gb.Room, gb => gb.Count) 
     select (new object[] { gbs.Key }) 
      .Concat(rooms.Select(r => l[r].Sum()).Cast<object>()) 
      .ToArray()) 
      .ToArray(); 

이 (가) 다음과 같은 생산 쿼리는 여전히 동일한 그리드의 오브젝트를 생성하지만, 첫 번째 형식보다 조금 더 읽기 쉽다.

이 정보가 도움이되기를 바랍니다.

+0

감사합니다. 시도했습니다. – user918064

+0

감사합니다. 결과를 Silverlight Datagrid에 바인딩합니다. 옵션 1은 날짜가있는 열과 텍스트가없는 roomcount가있는 7 줄만 표시합니다. 옵션 2는 .Concat에서 오류를 발생시킵니다 (예약 섹션의 b에서 객체에 concat에 대한 정의가 없음을 말함) 옵션 3이 가장 잘 보이지만 각 행을 배열로 나눠서 어떻게 바인딩 할 수 있는지 알 수 없습니다. itemsource 속성을 가진 DataGrid? 나는 아마 명백한 것을 놓치고 있습니까? – user918064