Linq Группировка Вопрос - PullRequest
       10

Linq Группировка Вопрос

3 голосов
/ 12 сентября 2011

Я работаю над простой системой бронирования конференц-зала.Каждой комнате для собраний назначается тип комнаты в зависимости от ее размера и т. Д. Я рассчитываю количество забронированных комнат из следующих:

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

В сгруппированные данные, такие как:

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

Мне удалось сделать это ранее, используя наборы данных, но мне нужно быть в состоянии сделать это в Linq для этого проекта, используя Linq для привлечения

Может кто-нибудь посоветовать лучший способ сделать это?

Спасибо

1 Ответ

0 голосов
/ 13 сентября 2011

Это то, что я сделал, когда столкнулся с такой проблемой:

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.

Обычно это вполне работоспособно.

Альтернативой является создание массива.массивов, которые представляют сетку, похожую на электронную таблицу.

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();

Это приводит к следующему:

    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 },
    };

Альтернативой альтернативе, в случае, если запрос выглядит немного волосатым, являетсячтобы сделать это:

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())));

Эта форма запроса все еще производит ту же сетку объектов, но она немного более читабельна, ИМХО, чем первая форма.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...