Походит на стандартный запрос LINQ проекции.
Используйте свойства навигации, замените foreach
на from
, var sample =
на let sample =
и не используйте пользовательские методы, но вставьте все в выражения инициализатора запроса и класса.
Таким образом, результат будет получен с помощью одного запроса к базе данных.
1011 * Е.Г. *
var data =
(from device in context.Devices
select new DeviceData
{
DeviceName = device.Name,
DeviceType = device.Type.ShortName,
Monitors =
(from monitor in device.Monitors
let sample = (from s in monitor.Samples
orderby s.Time descending
select s).FirstOrDefault()
select new MonitorSampleData
{
Name = monitor.Name,
Time = sample.Time,
Sequence = monitor.Sequence,
Type = monitor.DataType.Name,
Unit = monitor.UnitType.Name,
Value = sample.Value
}).ToList()
}).ToList();
Вместо
let sample = (from s in monitor.Samples
orderby s.Time descending
select s).FirstOrDefault()
вы можете попробовать функционально эквивалентную конструкцию
from sample in monitor.Samples
.DefaultIfEmpty()
.OrderByDescending(s => s.Time)
.Take(1)
что может улучшить перевод SQL.
Обновление: Я пропустил проверку if (sample != null)
в исходном коде. Таким образом, реальным эквивалентом LINQ будет вторая конструкция с удаленным .DefaultIfEmpty()
, что приведет к INNER JOIN
:
from sample in monitor.Samples
.OrderByDescending(s => s.Time)
.Take(1)