Группа Lambda Linq Iqueryable — добавить еще одну группу

У меня есть метод, который я использую для создания сводного отчета на основе параметров, выбранных пользователем в списках выбора, для подсчета количества тестов, завершенных в регионе с подмножеством местоположений в пределах диапазона дат.

Вот как выглядят данные: Количество завершенных тестов по местонахождению с 1 февраля 2015 г. по 1 марта 2015 г.

Total  TestType  Location  Region  Division
455    24 Hour   Lab 1     City 1  Division A
28     24 Hour   Lab 2     City 1  Division A
95     24 Hour   Clinic Z  City 2  Division A
189    24 Hour   Clinic Y  City 2  Division A

Вот как это может выглядеть для другого типа теста в тот же период времени:

Total  TestType  Location  Region  Division
285    48 Hour   Lab 1     City 1  Division A
12     48 Hour   Lab 2     City 1  Division A
75     48 Hour   Clinic Z  City 2  Division A
106    48 Hour   Clinic Y  City 2  Division A

Теперь пользователи хотели бы видеть сводную разбивку по testType в одном отчете (в SQL добавление еще одного атрибута в группу по). В моем списке выбора testTypeId я использую 0 как элемент «Все». В идеальном мире у меня было бы еще одно дополнение к IQueryable if testTypeId == 0, чтобы я мог сохранить тот же частный метод, а не писать новый запрос.

Вот как мы хотели бы, чтобы данные выглядели в ситуации «ВСЕ»:

Total  TestType  Location  Region  Division
455    24 Hour   Lab 1     City 1  Division A
285    48 Hour   Lab 1     City 1  Division A
59     12 Lead   Lab 1     City 1  Division A
28     24 Hour   Lab 2     City 1  Division A
12     48 Hour   Lab 2     City 1  Division A
95     24 Hour   Clinic Z  City 2  Division A
75     48 Hour   Clinic Z  City 2  Division A
5      12 Lead   Clinic Z  City 2  Division A
189    24 Hour   Clinic Y  City 2  Division A
106    48 Hour   Clinic Y  City 2  Division A
8      12 Lead   Clinic Y  City 2  Division A

В приведенном ниже примере показано, что у меня есть, и то, что я хотел бы добавить, но синтаксис говорит мне, что я не могу взять IQueryable, содержащий IGrouping, и преобразовать его в целевой тип IQueryable.

Может ли кто-нибудь указать мне в хорошем направлении здесь?

private CompletedCountReport GetCompletedCountsByRegion(int regionId, DateTime? startDate, DateTime? endDate, int testTypeId)
{
    var ccRpt = new CompletedCountReport { CompletedCounts = new List<CompletedCount>(), StartDate = startDate, EndDate = endDate, SelectedRegionID = regionId};

    var query = HolterTestDao.FindAll(new GetCompletedByRegionIdAndDates(regionId, startDate.Value, endDate.Value));

    // a specific test type was selected
    if (testTypeId > 0)
    {
        query = query.Where(x => x.HolterTestType == testTypeId);
    }
    // THIS IS WHAT I WANT TO ADD -> otherwise group by test type  <-  THIS IS WHAT I WANT TO ADD.
    if (testTypeId == 0)
    {
        query = query.GroupBy(x => x.HolterTestType);
    }
    // order by locationID within the region.
    query = query.OrderBy(x => x.Location.ID);

    var htList = query.ToList();

    // now Group by Location, to get counts. 
    var reportContents = htList.GroupBy(x => x.Location.ID);
    foreach (var r in reportContents)
    {
        var rList = r.ToList();

        var cc = new CompletedCount();
        var loc = LocationDao.FindById(r.Key);
        cc.Description = loc.Description;
        cc.RegionId = loc.Region.ID;
        cc.DivisionId = loc.Region.Division.ID;
        cc.TestTypeId = testTypeId;
        cc.Count = rList.Count;
        ccRpt.CompletedCounts.Add(cc);
    }

    return ccRpt;
}

person Jennifer S    schedule 03.03.2015    source источник
comment
Почему вы пытаетесь условно сгруппировать данные? Просто безоговорочно сгруппируйте данные.   -  person Servy    schedule 03.03.2015
comment
Итак, вы говорите, что всегда группируете как по местоположению, так и по типу теста? Иногда они хотят видеть только числа только для одного типа тестов, иногда они хотят видеть все типы тестов.   -  person Jennifer S    schedule 03.03.2015
comment
Должен сказать нам, как вы хотите разрешить IGrouping. Если несколько элементов объединены в один IGrouping, вы выбираете первый?   -  person James Sampica    schedule 03.03.2015
comment
@JenniferS Вы все еще можете условно фильтровать данные, просто не группируйте данные условно. Всегда группируйте, а затем при необходимости фильтруйте (или наоборот).   -  person Servy    schedule 03.03.2015
comment
Я всегда хочу группировать по местоположению. Я хочу группировать по типу теста только в том случае, если выбрано все, поэтому у меня есть отдельные подсчеты по типу теста, в противном случае я хочу только для выбранного типа теста.   -  person Jennifer S    schedule 03.03.2015
comment
Я не понимаю. Какой смысл группировать по testType, когда все ваши результаты представляют собой несколько testTypes, сгруппированных по местоположению? С тем же успехом вы можете вообще пропустить группировку по типу теста.   -  person James Sampica    schedule 03.03.2015
comment
Меня смущает ваш вопрос, потому что ваш пример данных «все» вообще не сгруппирован по типу теста (он просто упорядочен/сгруппирован по местоположению), что, как я думал, было тем, что вы пытались, но не смогли сделать. Если ваша цель - просто получить список, в котором все данные сгруппированы по местоположению, а каждое местоположение сгруппировано по типу теста, я думаю, вы можете просто использовать OrderBy(x => x.Location.ID).ThenBy(x => x.HolterTestType) на IQueryable и очень просто свой код.   -  person evanmcdonnal    schedule 03.03.2015
comment
То, что у меня было, очевидно, было неспособностью правильно общаться. Спасибо всем, что помогли мне обдумать это. Моя проблема не в группировке данных, а в моей условной логике, которая мне не нужна.   -  person Jennifer S    schedule 04.03.2015


Ответы (1)


Мое решение состояло в том, чтобы расположить OrderBy и HolterTestType, затем расположить GroupBy для основного содержимого, а затем добавить еще одну группировку в мой цикл по результатам, чтобы получить подсчеты по типу теста:

        query = query.OrderBy(x => x.Location.ID).ThenBy(x => x.HolterTestType);
        var htList = query.ToList();

        // now Group by Location. 
        var reportContents = htList.GroupBy(x => x.Location.ID);

        foreach (var r in reportContents)
        {
            //Group by TestType, to get counts.
            var t = r.GroupBy(x => x.HolterTestType);
            var tList = t.ToList();

            foreach(var u in tList)
            {
                var cc = new CompletedCount();
                var loc = LocationDao.FindById(r.Key);
                cc.Description = loc.Description;
                cc.RegionId = loc.Region.ID;
                cc.DivisionId = loc.Region.Division.ID;
                cc.TestTypeId = u.Key;
                cc.Count = u.Count();
                ccRpt.CompletedCounts.Add(cc);
            }
        }
person Jennifer S    schedule 04.03.2015