Home > Enterprise >  Is there any better way to filter the data based on grand grand child property in C#?
Is there any better way to filter the data based on grand grand child property in C#?

Time:01-24

I have a model which consist multi level of sub models. Now I want to filter the data based on most bottom level of child element. Please see the code (it's just for reference)

var treatmentItemss = new List<TreatmentItemViewModel>();

IEnumerable<IPublishedContent> countries = UmbracoContext.Content.GetById(contentId: 1063).Children(); 

foreach (var country in countries)
{
    IEnumerable<IPublishedContent> countys = country.Children();
    foreach (var county in countys)
    {
        IEnumerable<IPublishedContent> cities = county.Children();

        foreach (var city in cities)
        {
            IEnumerable<IPublishedContent> clinics = city.Children();
            foreach (var clinic in clinics)
            {
                IEnumerable<IPublishedContent> clinics2 = clinic.Children();
                foreach (var clinic2 in clinics2)
                {
                    IEnumerable<IPublishedContent> treatmentMenus = clinic2.Children();
                    foreach (var treatmentMenu in treatmentMenus)
                    {
                        IEnumerable<IPublishedContent> treatmentCategories = treatmentMenu.Children();
                        foreach (var treatmentCategory in treatmentCategories)
                        {
                            dynamic treatmentItems = treatmentCategory.Children();
                            foreach (var item in treatmentItems)
                            {
                                treatmentItemss.Add(new TreatmentItemViewModel
                                {
                                    SurgicalProcedure = item.SurgicalProcedure?.Name,
                                    NonSurgicalTreatment = item.NonSurgicalTreatment?.Name,
                                    Title = item.Title,
                                    Id = item.Id,
                                });
                            }
                        }
                    }
                }
            }
        }
    }
}

In above code I want to fetch the data base on SurgicalProcedure.Name for example, I want to get all the data of countries in which SurgicalProcedure.Name == "Angioplasty".

CodePudding user response:

You could consider writing an iterator method, that does the dirty job of doing the deep dive in the model, and exposes all the TreatmentItemViewModel as an enumerable sequence. Iterators are methods that contain yield return statements:

IEnumerable<TreatmentItemViewModel> GetTreatmentItems(int contentId)
{
    IEnumerable<IPublishedContent> countries = UmbracoContext.Content
        .GetById(contentId).Children(); 

    foreach (var country in countries)
    {
        foreach (var county in country.Children())
        {
            foreach (var city in county.Children())
            {
                foreach (var clinic in city.Children())
                {
                    foreach (var clinic2 in clinic.Children())
                    {
                        foreach (var treatmentMenu in clinic2.Children())
                        {
                            foreach (var treatmentCategory in treatmentMenu.Children())
                            {
                                foreach (var item in treatmentCategory.Children())
                                {
                                    yield return new TreatmentItemViewModel()
                                    {
                                        SurgicalProcedure = item
                                            .SurgicalProcedure?.Name,
                                        NonSurgicalTreatment = item
                                            .NonSurgicalTreatment?.Name,
                                        Title = item.Title,
                                        Id = item.Id,
                                    };
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

You could then query this sequence with the Where LINQ operator:

TreatmentItemViewModel[] results = GetTreatmentItems(contentId: 1063)
    .Where(x => x.SurgicalProcedure == "Angioplasty")
    .ToArray();

Enumerating all these TreatmentItemViewModel entities could result in a lot of garbage, so you could consider defining this type as a struct instead of class.

CodePudding user response:

Having nested code like this is the not good at all. I think you should change your design to support unlimited level of tree grandchildren and ancestors.

To understand the topic checkout this question and answers.

  • Related