Будучи довольно новым для 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
.
Ссылки