LINQ вложенный (внутренний) JOIN не присоединяет детей - PullRequest
0 голосов
/ 05 февраля 2020

Будучи довольно новым для LINQ, я, вероятно, не ищу правильные условия поиска, поэтому я спрашиваю здесь.

У меня есть объект передачи данных (DTO) для текущего временного шага и DTO для предыдущего временного шага. Я намереваюсь СОХРАНИТЬ эту информацию в единый (вложенный) список и отобразить процентные изменения (для всех записей списка). Вложенные содержат узлы типа myObject. Другими словами, список состоит из пары родительских записей и (различных уровней) дочерних элементов одного типа. Шаг слияния в направлении dataFullDto отлично работает только для родительских записей, для дочерних записей целевой объект не содержит информацию предыдущего временного шага, PreviousValue и DeltaPercentage равны null. Можно ли выполнить это действие на всех узлах вложенного списка без foreach l oop?

Предположим, что есть функция inputData(int timestep), которая возвращает все необходимые данные. Я унаследовал следующий код, который содержит LINQ внутренний JOIN :

var dataCurrentDto = inputData(time).GroupBy(x => x.Position) // Position just contains .Id and .Name
    .Select(x => new myObject {
       PositionId = x.Key?.Id,
       PositionName = x.Key?.Name,
       children = x.Select(Mapper.Map<myObjectDto>),
       Value = x.Sum(y => y.Value),
       PreviousValue = 0, // just to initialize, to be overwritten asap
       DeltaPercentage = 0, // dito
    });
var dataPreviousDto = inputData.Select(time-1).GroupBy(x => x.Position)
    .Select(x => new myObject {
        PositionId = x.Key?.Id,   
        PositionName = x.Key?.Name,
        children = x.Select(Mapper.Map<myObjectDto>),
        Value = x.Sum(y => y.Value),
    });   
dataFullDto = from current in dataCurrentDto join previous in dataPrevious on
              new { current.PositionId, current.SubPositionId }
              equals new { previous.PositionId, previous.SubPositionId }
              select new myObjectDto {
                 PositionId = current.PositionId,
                 PositionName = current.PositionName,
                 children = current.children,
                 SubPositionId = current.SubPositionId,
                 SubPositionName = current.SubPositionName,
                 Value = current.Value,
                 PreviousValueAdjusted = previous.Value,
                 DeltaPercentage = (previous.!= null || previous.Value != 0) ?
                                   (current.Value - previous.Value) / previous.Value : null,
             };

Я предполагаю, что GroupBy() был добавлен, чтобы включить сумму по дочерним элементам. Но очевидно, что сумма за покидающий узел не просто возвращает значение самого свойства?

DTO определяется следующим образом:

namespace API.Models
{
    public class myObjectDto
    {
        public int? PositionId { get; set; }
        public string PositionName { get; set; }
        public int SubPositionId { get; set; }
        public string SubPositionName { get; set; }
        public decimal? Value { get; set; }
        public decimal? PreviousValue { get; set; }
        public decimal? DeltaPercentage { get; set; }
    }
}

Родительские записи имеют SubPositionId = null и SubPositionName = null, дочерние записи имеют заполненные эти два поля. Листовые узлы имеют children=null.

Ссылки

...