S
S
Senture2021-06-26 18:18:32
C++ / C#
Senture, 2021-06-26 18:18:32

C# LINQ GroupBy, multi-nested grouping, how to do it right?

Good day to all!

I have the following list that needs to be grouped:

spoiler

var cntr = new List<Contract>()
            {
                new Contract
                {
                    ContractNumber = "1",
                    ContractorId = Guid.Parse("43ad7323-4d5d-4699-b290-a3ebbf4a028a"),
                    DateStart = new DateTime(2021, 1, 1),
                    DateEnd = new DateTime(2023, 12, 31),
                    GroupFields = new List<Guid>
                    {
                        Guid.Parse("0a67b6af-71b1-4f3a-9cdf-5195307177ef"),
                        Guid.Parse("21471679-0f69-437e-b704-43119deae1c0"),
                        Guid.Parse("66ae9449-9a3e-4f35-91d5-b90784604ef4"),
                    },
                    Id = Guid.Parse("cbabff12-18cb-44f2-a5f0-ffae42f4cb9c"),
                    IsAgreed = true,
                    Services = new List<Guid>
                    {
                        Guid.Parse("5c4d0a8a-916e-44a1-80f0-5b3b1fc31714"),
                        Guid.Parse("3bc308ec-0f74-4d59-a889-a9bff1fc3d08"),
                        Guid.Parse("342baf11-d69c-4c36-871c-d640a774daf0"),
                    },
                    IsAdditional = false,
                    ContractId = null,
                },
                new Contract
                {
                    ContractNumber = "2",
                    ContractorId = Guid.Parse("43ad7323-4d5d-46f1-b290-a3ebbf4a0281"),
                    DateStart = new DateTime(2022, 1, 1),
                    DateEnd = new DateTime(2025, 12, 31),
                    GroupFields = new List<Guid>
                    {
                        Guid.Parse("0a67b6af-71b1-4f3a-9cdf-5195307177ef"),
                        Guid.Parse("21471679-0f69-437e-b704-43119deae1c0"),
                        Guid.Parse("0a6786af-71b1-4f3a-9cdf-5195307177e1"),
                        Guid.Parse("21472679-0f69-437e-b704-43119deae1c1"),
                        Guid.Parse("66ae3449-9a3e-4f35-91d5-b90784604ef1"),
                    },
                    Id = Guid.Parse("cba4ff12-18cb-44f2-a5f0-ffae42f4cb91"),
                    IsAgreed = true,
                    Services = new List<Guid>
                    {
                        Guid.Parse("574d0a8a-916e-44a1-80f0-5b3b1fc31711"),
                        Guid.Parse("36c308ec-0f74-4d59-a889-a9bff1fc3d01"),
                        Guid.Parse("352baf11-d69c-4c36-871c-d640a774daf1"),
                    },
                    IsAdditional = false,
                    ContractId = null,
                },
                new Contract
                {
                    ContractNumber = "3",
                    ContractorId = Guid.Parse("43a17323-4d5d-4699-b290-a3ebbf4a0282"),
                    DateStart = new DateTime(2019, 1, 1),
                    DateEnd = new DateTime(2026, 12, 31),
                    GroupFields = new List<Guid>
                    {
                        Guid.Parse("0a67b6af-71b1-4f3a-9cdf-5195307177ef"),
                        Guid.Parse("21471679-0f69-437e-b704-43119deae1c0"),
                        Guid.Parse("0a67b6af-7121-4f3a-9cdf-5195307177e2"),
                        Guid.Parse("21471679-0f29-437e-b704-43119deae1c2"),
                        Guid.Parse("66ae9449-9a2e-4f35-91d5-b90784604ef2"),
                    },
                    Id = Guid.Parse("cbabff12-12cb-44f2-a5f0-ffae42f4cb92"),
                    IsAgreed = true,
                    Services = new List<Guid>
                    {
                        Guid.Parse("5c4d0a8a-9161-44a1-80f0-5b3b1fc31712"),
                        Guid.Parse("3bc308ec-0f71-4d59-a889-a9bff1fc3d02"),
                        Guid.Parse("342baf11-d691-4c36-871c-d640a774daf2"),
                    },
                    IsAdditional = false,
                    ContractId = null,
                }
            };



Grouping rules:
1. First by year (i.e. if dateStart(2021) is the end date(2024), then we get 4 years, 2021, 2022, 2023, 2024).
2. In each year, there should be a grouping by separate GroupFields (if you do just GroupBy, it groups by List, but you need by each individual Guid).
3. In each GroupField(Guid) grouping by ContractorId.

I'm not familiar with GroupBy, and the deadlines are burning. Now I’m looking for it myself, google it, but I’m not sure that such a grouping can be done in a similar way. (I think it can make different LINQ queries, but I still don’t understand how.)

The main goal is to avoid nested loops (it’s not difficult for them, but it turns out very bad code).

Maybe this info is useful: this list of objects is taken from the database (some fields are stored in JSON format).

PS It would be great if someone tells me where you can see examples of such multi-nested groupings. Or who will stumble upon something useful to read.

Thanks to all!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
d-stream, 2021-06-26
@d-stream

Actually, if not "immediately", then the source-grouping - the resulting-grouping, and so on, is exactly step by step.
Plus, it's worth catching a compromise between readability and performance. So that it doesn’t work like with regular expressions, which are already unreadable a day or two after writing ... (greetings from the full regex of checking email via rfc for five pages)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question