Создание вложенного Dto для возврата данных, где составной ключ присутствует в массиве - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь создать Dto, которое будет отображать множество вложенных данных на основе введенных пользователем параметров из интерфейса веб-приложения.

public async Task<IActionResult> GetData(int? version,
                                             int[] subSpecialty,
                                             int[] pathway,
                                             int[] job,
                                             int[] opActivity,
                                             int[] pointOfDelivery,
                                             int[] theatreList)

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

У меня было несколько попыток сопоставить эти данные безуспешно, моя текущая попытка кажется, что она должна работать и выглядит так:

var dto = await
            _dbContext.ModelVersion
            .Where(mv => version == mv.Id)
            .Select(mv => new DataGetDto
            {
                ModelId = mv.Id,
                SubSpecialtyDto = mv.SubSpecialties
                                    .Where(ss => ss.ModelId == version && subSpecialty.Contains(ss.SubSpecialtyTypeId))
                                    .Select(ss => new SubSpecialtyDto
                                    {
                                        CostOp = ss.CostOp,
                                        CostTh = ss.CostTh,
                                        ModelId = ss.ModelId,
                                        SubSpecialtyTypeId = ss.SubSpecialtyTypeId,
                                        FacilityActivityDto = mv.FacilityActivities
                                                                .Where(fa => fa.ModelId == version && pointOfDelivery.Contains(fa.PointOfDeliveryId) && pathway.Contains(fa.PathwayId) && subSpecialty.Contains(fa.SubSpecialtyTypeId))
                                                                .Select(fa => new FacilityActivityDto
                                                                {
                                                                    PatientCases = fa.PatientCases,
                                                                    AverageIncome = fa.AverageIncome,
                                                                    CostToBookSinglePatient = fa.CostToBookSinglePatient,
                                                                    AverageCaseTime = fa.AverageCaseTime,
                                                                    PoDproportion = fa.PoDproportion,
                                                                    LengthOfStay = fa.LengthOfStay,
                                                                    PatientHandlingCost = fa.PatientHandlingCost,
                                                                    CostPerDay = fa.CostPerDay,
                                                                    BedOccupancy = fa.BedOccupancy,
                                                                    InplantCost = fa.InplantCost,
                                                                    OverHead = fa.OverHead,
                                                                    ModelId = fa.ModelId,
                                                                    PointOfDeliveryId = fa.PointOfDeliveryId,
                                                                    PathwayId = fa.PathwayId,
                                                                    SubSpecialtyTypeId = fa.SubSpecialtyTypeId
                                                                }),
                                        OutPatientActivityDto = mv.OutPatientActivities
                                                                  .Where(opa => opa.ModelId == version && opActivity.Contains(opa.ActivityId) && pathway.Contains(opa.PathwayId) && subSpecialty.Contains(opa.SubSpecialtyTypeId))
                                                                  .Select(opa => new OutPatientActivityDto
                                                                  {
                                                                      PatientsSeenOp = opa.PatientsSeenOp,
                                                                      AverageIncomeOp = opa.AverageIncomeOp,
                                                                      ConversionRate = opa.ConversionRate,
                                                                      ModelId = opa.ModelId,
                                                                      ActivityId = opa.ActivityId,
                                                                      PathwayId = opa.PathwayId,
                                                                      SubSpecialtyTypeId = opa.SubSpecialtyTypeId
                                                                  }),
                                        OutPatientOperationalFactorDto = mv.OutPatientOperationalFactors
                                                                           .Where(opof => opof.ModelId == version && opActivity.Contains(opof.ActivityId) && subSpecialty.Contains(opof.SubSpecialtyTypeId))
                                                                           .Select(opof => new OutPatientOperationalFactorDto
                                                                           {
                                                                               BookingRateOp = opof.BookingRateOp,
                                                                               DnarateOp = opof.DnarateOp,
                                                                               PatientCancellationRateOp = opof.PatientCancellationRateOp,
                                                                               HospitalCancellationRateOp = opof.HospitalCancellationRateOp,
                                                                               PatientLateNoticeRateOp = opof.PatientLateNoticeRateOp,
                                                                               HospitalLateNoticeRateOp = opof.HospitalLateNoticeRateOp,
                                                                               CostToBookSingleOutPatient = opof.CostToBookSingleOutPatient,
                                                                               ModelId = opof.ModelId,
                                                                               ActivityId = opof.ActivityId,
                                                                               SubSpecialtyTypeId = opof.SubSpecialtyTypeId
                                                                           }),
                                        SkillMixDistributionDto = mv.SkillMixDistributions
                                                                    .Where(smd => smd.ModelId == version && opActivity.Contains(smd.JobTypeId) && pathway.Contains(smd.PathwayId) && subSpecialty.Contains(smd.SubSpecialtyTypeId))
                                                                    .Select(smd => new SkillMixDistributionDto
                                                                    {
                                                                        WorkingWeeksPerYearOp = smd.WorkingWeeksPerYearOp,
                                                                        WorkingWeeksPerYearTh = smd.WorkingWeeksPerYearTh,
                                                                        CostPerPa = smd.CostPerPa,
                                                                        DistributionOp = smd.DistributionOp,
                                                                        DistributionTh = smd.DistributionTh,
                                                                        AdminTimeOp = smd.AdminTimeOp,
                                                                        SetupTimeOp = smd.SetupTimeOp,
                                                                        CacheUpTimeOp = smd.CacheUpTimeOp,
                                                                        PatientFacingTimeOp = smd.PatientFacingTimeOp,
                                                                        ModelId = smd.ModelId,
                                                                        JobTypeId = smd.JobTypeId,
                                                                        PathwayId = smd.PathwayId,
                                                                        SubSpecialtyTypeId = smd.SubSpecialtyTypeId,

                                                                    }),
                                        TheatreListStructureDto = mv.TheatreListStructures
                                                                    .Where(tls => tls.ModelId == version && opActivity.Contains(tls.TheatreListTypeId) && pathway.Contains(tls.SubSpecialtyTypeId))
                                                                    .Select(tls => new TheatreListStructureDto
                                                                    {
                                                                        PreOpWardRound = tls.PreOpWardRound,
                                                                        PostOpWardRound = tls.PostOpWardRound,
                                                                        FacingPatientTime = tls.FacingPatientTime,
                                                                        BreakTime = tls.BreakTime,
                                                                        PreferredSessionType = tls.PreferredSessionType,
                                                                        ModelId = tls.ModelId,
                                                                        TheatreListTypeId = tls.TheatreListTypeId,
                                                                        SubSpecialtyTypeId = tls.SubSpecialtyTypeId
                                                                    }),
                                        TheatreOperationalFactorDto = mv.TheatreOperationalFactors
                                                                        .Where(tof => tof.ModelId == version && opActivity.Contains(tof.PointOfDeliveryId) && subSpecialty.Contains(tof.SubSpecialtyTypeId))
                                                                        .Select(tof => new TheatreOperationalFactorDto
                                                                        {
                                                                            CostToRunListTh = tof.CostToRunListTh,
                                                                            PreOpAnaesthetic = tof.PreOpAnaesthetic,
                                                                            PostOpAnaesthetic = tof.PostOpAnaesthetic,
                                                                            KnifeToSkin = tof.KnifeToSkin,
                                                                            Gaps = tof.Gaps,
                                                                            LateStart = tof.LateStart,
                                                                            EarlyFinish = tof.EarlyFinish,
                                                                            InSessionUtilisation = tof.InSessionUtilisation,
                                                                            ModelId = tof.ModelId,
                                                                            PointOfDeliveryId = tof.PointOfDeliveryId,
                                                                            SubSpecialtyTypeId = tof.SubSpecialtyTypeId
                                                                        })
                                    })

            })
            .ToListAsync();

Когда я пытаюсь проверить этот код, я пишу это в URL.

Data?version=1&subSpecialty=1&pathway=1&job=1&opActivity=1&pointOfDelivery=1&theatreList=1

Это удачно отображает идентификатор версии (ModelId), как и ожидалось, но возвращает ошибку типа System.InvalidOperationException при входе на первый уровень вложенности: переменное изображение часов

-       Current '((System.Linq.AsyncEnumerable.AsyncIterator<Medicor.Portal.Models.DacPlannerDtos.SubSpecialtyDto>)((Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.EnumerableAdapter<Medicor.Portal.Models.DacPlannerDtos.SubSpecialtyDto>)(new System.Collections.Generic.ICollectionDebugView<Medicor.Portal.Models.DacPlannerDtos.DataGetDto>(dto).Items[0]).SubSpecialtyDto).Results).Current' threw an exception of type 'System.InvalidOperationException'   Medicor.Portal.Models.DacPlannerDtos.SubSpecialtyDto {System.InvalidOperationException}

Мои Dtos сформированы таким образом, что я также чувствую, что они правильные.

DataGetDto с начальным вложенным Dto:

public class DataGetDto
{

    public int ModelId { get; set; }

    public IEnumerable<SubSpecialtyDto> SubSpecialtyDto { get; set; }

}

SubSpecialtyDto с дополнительными вложенными Dtos:

public class SubSpecialtyDto
{
    [Range(typeof(Decimal), "0", "999999")]
    public decimal? CostOp { get; set; } //Not sure

    [Range(typeof(Decimal), "0", "999999")]
    public decimal? CostTh { get; set; } //Not sure

    public int SubSpecialtyTypeId { get; set; }

    public int ModelId { get; set; }

    public IEnumerable<FacilityActivityDto> FacilityActivityDto { get; set; }
    public IEnumerable<OutPatientActivityDto> OutPatientActivityDto { get; set; }
    public IEnumerable<OutPatientOperationalFactorDto> OutPatientOperationalFactorDto { get; set; }
    public IEnumerable<SkillMixDistributionDto> SkillMixDistributionDto { get; set; }
    public IEnumerable<TheatreListStructureDto> TheatreListStructureDto { get; set; }
    public IEnumerable<TheatreOperationalFactorDto> TheatreOperationalFactorDto { get; set; }
}

OutPatientActivityDto в качестве примера вложенного Dtos второго уровня:

public class OutPatientActivityDto
{
    [Range(0, int.MaxValue)]
    public int? PatientsSeenOp { get; set; }

    [Range(typeof(Decimal), "0", "999999")]
    public decimal? AverageIncomeOp { get; set; }

    [Range(typeof(Decimal), "0", "1")]
    public decimal? ConversionRate { get; set; }

    public int ActivityId { get; set; }

    public int SubSpecialtyTypeId { get; set; }

    public int PathwayId { get; set; }

    public int ModelId { get; set; }

}

Поэтому мои вопросы:

Действительны ли структуры Dto?

Как можно отредактировать метод GetData, чтобы удалить текущую ошибку и правильно отобразить данные?

Если что-то слишком расплывчатое или отсутствует, спросите, и я обязательно добавлю больше информации. Заранее спасибо!


UPDATE

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

Ошибка присутствует только при отладке через Watch, нет принудительного исключения, и когда я тестирую код с помощью URL, возвращается пустая страница (я еще не настроил представление, так что это ожидается).

Кажущийся рабочий код ниже с использованием Оптимизация коррелированного подзапроса :

            var dto = 
            _dbContext.ModelVersion
            .Where(mv => version == mv.Id)
            .Select(mv => new DataGetDto
            {
                ModelId = mv.Id,
                SubSpecialtyDto = mv.SubSpecialties
                                    .Where(ss => ss.ModelId == version && subSpecialty.Contains(ss.SubSpecialtyTypeId))
                                    .Select(ss => new SubSpecialtyDto
                                    {
                                        CostOp = ss.CostOp,
                                        CostTh = ss.CostTh,
                                        ModelId = ss.ModelId,
                                        SubSpecialtyTypeId = ss.SubSpecialtyTypeId,
                                        FacilityActivityDto = mv.FacilityActivities
                                                                .Where(fa => fa.ModelId == version && pointOfDelivery.Contains(fa.PointOfDeliveryId) && pathway.Contains(fa.PathwayId) && subSpecialty.Contains(fa.SubSpecialtyTypeId))
                                                                .Select(fa => new FacilityActivityDto
                                                                {
                                                                    PatientCases = fa.PatientCases,
                                                                    AverageIncome = fa.AverageIncome,
                                                                    CostToBookSinglePatient = fa.CostToBookSinglePatient,
                                                                    AverageCaseTime = fa.AverageCaseTime,
                                                                    PoDproportion = fa.PoDproportion,
                                                                    LengthOfStay = fa.LengthOfStay,
                                                                    PatientHandlingCost = fa.PatientHandlingCost,
                                                                    CostPerDay = fa.CostPerDay,
                                                                    BedOccupancy = fa.BedOccupancy,
                                                                    InplantCost = fa.InplantCost,
                                                                    OverHead = fa.OverHead,
                                                                    ModelId = fa.ModelId,
                                                                    PointOfDeliveryId = fa.PointOfDeliveryId,
                                                                    PathwayId = fa.PathwayId,
                                                                    SubSpecialtyTypeId = fa.SubSpecialtyTypeId
                                                                }).ToList(),
                                        OutPatientActivityDto = mv.OutPatientActivities
                                                                  .Where(opa => opa.ModelId == version && opActivity.Contains(opa.ActivityId) && pathway.Contains(opa.PathwayId) && subSpecialty.Contains(opa.SubSpecialtyTypeId))
                                                                  .Select(opa => new OutPatientActivityDto
                                                                  {
                                                                      PatientsSeenOp = opa.PatientsSeenOp,
                                                                      AverageIncomeOp = opa.AverageIncomeOp,
                                                                      ConversionRate = opa.ConversionRate,
                                                                      ModelId = opa.ModelId,
                                                                      ActivityId = opa.ActivityId,
                                                                      PathwayId = opa.PathwayId,
                                                                      SubSpecialtyTypeId = opa.SubSpecialtyTypeId
                                                                  }).ToList(),
                                        OutPatientOperationalFactorDto = mv.OutPatientOperationalFactors
                                                                           .Where(opof => opof.ModelId == version && opActivity.Contains(opof.ActivityId) && subSpecialty.Contains(opof.SubSpecialtyTypeId))
                                                                           .Select(opof => new OutPatientOperationalFactorDto
                                                                           {
                                                                               BookingRateOp = opof.BookingRateOp,
                                                                               DnarateOp = opof.DnarateOp,
                                                                               PatientCancellationRateOp = opof.PatientCancellationRateOp,
                                                                               HospitalCancellationRateOp = opof.HospitalCancellationRateOp,
                                                                               PatientLateNoticeRateOp = opof.PatientLateNoticeRateOp,
                                                                               HospitalLateNoticeRateOp = opof.HospitalLateNoticeRateOp,
                                                                               CostToBookSingleOutPatient = opof.CostToBookSingleOutPatient,
                                                                               ModelId = opof.ModelId,
                                                                               ActivityId = opof.ActivityId,
                                                                               SubSpecialtyTypeId = opof.SubSpecialtyTypeId
                                                                           }).ToList(),
                                        SkillMixDistributionDto = mv.SkillMixDistributions
                                                                    .Where(smd => smd.ModelId == version && opActivity.Contains(smd.JobTypeId) && pathway.Contains(smd.PathwayId) && subSpecialty.Contains(smd.SubSpecialtyTypeId))
                                                                    .Select(smd => new SkillMixDistributionDto
                                                                    {
                                                                        WorkingWeeksPerYearOp = smd.WorkingWeeksPerYearOp,
                                                                        WorkingWeeksPerYearTh = smd.WorkingWeeksPerYearTh,
                                                                        CostPerPa = smd.CostPerPa,
                                                                        DistributionOp = smd.DistributionOp,
                                                                        DistributionTh = smd.DistributionTh,
                                                                        AdminTimeOp = smd.AdminTimeOp,
                                                                        SetupTimeOp = smd.SetupTimeOp,
                                                                        CacheUpTimeOp = smd.CacheUpTimeOp,
                                                                        PatientFacingTimeOp = smd.PatientFacingTimeOp,
                                                                        ModelId = smd.ModelId,
                                                                        JobTypeId = smd.JobTypeId,
                                                                        PathwayId = smd.PathwayId,
                                                                        SubSpecialtyTypeId = smd.SubSpecialtyTypeId,

                                                                    }).ToList(),
                                        TheatreListStructureDto = mv.TheatreListStructures
                                                                    .Where(tls => tls.ModelId == version && theatreList.Contains(tls.TheatreListTypeId) && pathway.Contains(tls.SubSpecialtyTypeId))
                                                                    .Select(tls => new TheatreListStructureDto
                                                                    {
                                                                        PreOpWardRound = tls.PreOpWardRound,
                                                                        PostOpWardRound = tls.PostOpWardRound,
                                                                        FacingPatientTime = tls.FacingPatientTime,
                                                                        BreakTime = tls.BreakTime,
                                                                        PreferredSessionType = tls.PreferredSessionType,
                                                                        ModelId = tls.ModelId,
                                                                        TheatreListTypeId = tls.TheatreListTypeId,
                                                                        SubSpecialtyTypeId = tls.SubSpecialtyTypeId
                                                                    }).ToList(),
                                        TheatreOperationalFactorDto = mv.TheatreOperationalFactors
                                                                        .Where(tof => tof.ModelId == version && pointOfDelivery.Contains(tof.PointOfDeliveryId) && subSpecialty.Contains(tof.SubSpecialtyTypeId))
                                                                        .Select(tof => new TheatreOperationalFactorDto
                                                                        {
                                                                            CostToRunListTh = tof.CostToRunListTh,
                                                                            PreOpAnaesthetic = tof.PreOpAnaesthetic,
                                                                            PostOpAnaesthetic = tof.PostOpAnaesthetic,
                                                                            KnifeToSkin = tof.KnifeToSkin,
                                                                            Gaps = tof.Gaps,
                                                                            LateStart = tof.LateStart,
                                                                            EarlyFinish = tof.EarlyFinish,
                                                                            InSessionUtilisation = tof.InSessionUtilisation,
                                                                            ModelId = tof.ModelId,
                                                                            PointOfDeliveryId = tof.PointOfDeliveryId,
                                                                            SubSpecialtyTypeId = tof.SubSpecialtyTypeId
                                                                        }).ToList()
                                    })

            });
...