У нас есть несколько машин с подключенными устройствами.Не на всех машинах установлены устройства, и устройства можно перемещать между машинами.Устройства генерируют ошибки, и нам нужно сосчитать эти ошибки, произошедшие за прошедший день.
У нас есть четыре таблицы: машины (с Id и кодом), устройства (с Id и кодом), таблица сопряжения DevicesMachines (Id, IdMachine, IdDevice, From datetime, To datetime) и ошибки (Id, IdDevice, Moment datetime, Description).
Рабочий запрос SQL выглядит так:
Select m.Id, m.Code,
Coalesce(d.Code, 'NA') As DeviceCode,
Coalesce(Err.ErrorCnt,0) As ErrorCnt
From Machines As m
Left Outer Join (Select IdMachine, IdDevice From DevicesMachines as dm
Where GetDate() Between dm.From And dm.To) As dm on m.Id=dm.IdMachine
Left Outer Join Devices As d on dm.IdDevice=d.Id
Left outer join
( Select IdMachine, Count(Id) As ErrorCnt From Errors as er
Where er.Moment >= DateAdd(day,-1,GetUtcDate())
Group By IdMachine) As Err
On m.Id=Err.IdMachine
Я пробовал многосинтаксис, один из которых приведен ниже:
using ( DataContextM dcMachines = new dataContextM())
{
IEnumerable<MachineRow> lstM =
from m in dcMachines.Machines
from dm in dcMachines.DevicesMachines.Where(dm => (dm.IdMachine == m.Id) && (dm.From <= DateTime.Now) && (dm.To >= DateTime.Now)).DefaultIfEmpty()
from d in dcMachines.Devices.Where(d => d.Id == dm.IdDevice).DefaultIfEmpty()
from er in dcMachines.Errors
.Where(er => (er.Moment >= DateTime.Now) && (er.Moment <= DateTime.Now.AddDays(-1)))
.GroupBy(er => er.IdMachine)
.Select(er => new { IdMachine = er.Key, ErrorCnt = er.Count() })
.Where(er=> er.IdMachine==m.Id).DefaultIfEmpty()
select new MachineRow
{
Id = amId,
Code = m.Code,
DeviceCode = (d == null) ? "NA" : d.DeviceCode,
IdDevice = (d == null) ? 0: d.Id,
ErrorCnt = (er == null) ? 0 : er.ErrorCnt
};
}
Мне не удалось найти правильный синтаксис Linq, и мне нужна ваша помощь.
Спасибо, Даниэль