Я бы сказал, что сложно из-за вложенности - но на самом деле не нужно. Вот пример запроса, который даст те же результаты (я думаю), но проще ...
IList<ListViewItem> data = runAnalysis.PassAnalyses
.Cast<PassAnalysis>()
.Select(pass => pass.GetValue(PeakStatistics.PeakStatisticsProperty))
.SelectMany(peakStats => peakStats.Statistics)
.Where(statisticsBase => statisticsBase.Name == statisticType)
.Select(statisticsBase => new ListViewItem {Content = statisticsBase})
.ToList();
Без вложенности, это легко увидеть, как преобразование идет:
- Start с PassAnalyses
- в ролях каждый элемент в PassAnalysis
- Выберите PeakStatistics
- от каждого элемента, выберите все статистики внутри нее, и придавить эту последовательность
- фильтр любой статистики с неправильным именем
- Преобразование каждого результата в ListViewItem
- Преобразовать всю последовательность в список
На данный момент, это легко преобразовать его в выражение запроса:
IList<ListViewItem> data =
(from PassAnalysis pass in runAnalysis.PassAnalyses
from statsBase in pass.GetValue(PeakStatistics.PeakStatisticsProperty)
.Statistics
where statsBase.Name == statisticType
select new ListViewItem { Content = statsBase })
.ToList();
Обратите внимание, что я выбрал первый вариант Select и SelectMany; вы можете использовать предложение let
, если хотите. Также я использовал явный тип для переменной диапазона pass
, чтобы заставить компилятор генерировать вызов Cast<PassAnalysis >()
.
Это слегка отличается от оригинальной версии, так как он будет использовать другую форму SelectMany
, распространяющейся исходное значение pass
тоже, но результаты будут такими же.
Вызов ToList()
в конце несколько некрасиво, как нет никакого выражения запроса синтаксис для этого ... но вы можете использовать промежуточную переменную для этого:
var query = ...;
IList<ListViewItem> data = query.ToList();
делает все, что в 1 запрос всегда лучше, чем в много маленьких .... особенно с linq. – Stefanvds
Почему? Ничто из этого не выполняется, пока вы не перечислите результаты. – Mark