Smooth and group complex objects in Linq and save zero children

I have a list of a complex object with a name RouteExportthat I am trying to smooth and group based on value CustomerNumberso that it returns an anonymous object that looks like

{ CustomerNumber = "1235", Route = route1, Section = section2, Sequence = sequence2 } 

or

{ CustomerNumber = "1234", Route = route1, Section = null, Sequence = null }

Models look like this:

public class RouteExport
{
    public string Name { get; set; }
    public string Term { get; set; }
    public List<string> CustomerNumbers { get; set; }
    public List<SectionExport> Sections { get; set; }
}

public class SectionExport
{
    public string Name { get; set; }
    public List<string> CustomerNumbers { get; set; }
    public List<SequenceExport> Sequences { get; set; }
}

public class SequenceExport
{
    public string Name { get; set; }
    public List<string> CustomerNumbers { get; set; }
}

Each of the objects has a CustomerNumber list containing the customer number, if they are in this route / section / sequence. I would like to create a group of each object based on this customer number. So far I have used this:

var flattendExport = exportViewModel.ExportContainer.Routes
            .SelectMany(rt => rt.Sections
                .SelectMany(sec => sec.Sequences
                    .SelectMany(seq => seq.CustomerNumbers
                        .Select(custNum => new { rt, sec, seq, custNum })))).ToList();

which aligns an object but does not group it with CustomerNumberand does not return null for a section or sequence.

, , CustomerNumbers null, ?

, . , :

var data = new List<RouteExport>
{
    new RouteExport
    {
        CustomerNumbers = new List<string> { "1", "2" },
        Sections = new List<SectionExport>
        {
            new SectionExport()
            {
                CustomerNumbers = new List<string> { "1" },
                Sequences = new List<SequenceExport> {
                    new SequenceExport()
                    {
                        CustomerNumbers = new List<string> { "1" }
                    }
                }
            }
        }
    }
};

:

{ CustomerNumber = "1", Route = route1, Section = section1, Sequence = sequence1},
{ CustomerNumber = "2", Route = route1, Section = null, Sequence = null}
+4
2

LINQ DefaultIfEmpty, , , Sections . . https://msdn.microsoft.com/en-us/library/bb355419(v=vs.110).aspx

.SelectMany(...) :

.DefaultIfEmpty(new { rt, null, null, cystNum })

" , , ".

EDIT: , :

 var res = data.SelectMany(r => r.CustomerNumbers
            .SelectMany(c => r.Sections.Where(s => s.CustomerNumbers.Contains(c))
                .SelectMany(s => s.Sequences
                  .Select(seq => new { CustomerNumber = c, Route = r, Section = s, Sequence = seq }))
                .DefaultIfEmpty(new { CustomerNumber = c, Route = r, Section = (SectionExport)null, Sequence = (SequenceExport)null })))
                .ToList();
+1

, DefaultIfEmptyOrNull:

public static IEnumerable<T> DefaultIfEmptyOrNull<T>(this IEnumerable<T> source)
{
    return (source ?? Enumerable.Empty<T>()).DefaultIfEmpty();
}

:

var flattendExport = exportViewModel.ExportContainer.Routes
    .SelectMany(rt => (rt?.Sections).DefaultIfEmptyOrNull()
        .SelectMany(sec => (sec?.Sequences).DefaultIfEmptyOrNull()
            .SelectMany(seq => (seq?.CustomerNumbers).DefaultIfEmptyOrNull()
                .Select(custNum => new { rt, sec, seq, custNum })))).ToList();

:

var flattendExport = (from rt in exportViewModel.ExportContainer.Routes
                      from sec in (rt?.Sections).DefaultIfEmptyOrNull()
                      from seq in (sec?.Sequences).DefaultIfEmptyOrNull()
                      from custNum in (seq?.CustomerNumbers).DefaultIfEmptyOrNull()
                      select new { rt, sec, seq, custNum }).ToList();

, , , (sec?.Sequences) , , sec null, DefaultIfEmptyOrNull , .

+1

Source: https://habr.com/ru/post/1695486/


All Articles