0

Я думаю, что у меня возникла путаница с этим. Моя база данных выглядит следующим образом:Код LinqToEntities для запроса, требующего одного объекта, возвращаемого корневым узлом foreach?

Locations [root] 
    Inspections [level1] 
     InspectionItems [level2] 
      InspectionReadings [level3]  
    Areas [level1] 
     Inspections [level2] 
      InspectionItems [level3] 
       InspectionReadings [level4] 

каждая таблица связывает Guid с предыдущей таблицы и таблицы Осмотры имеет обнуляемого Areaid, так что это может быть прямым потомком места.

Что мне нужно

for each Location 
    {take all InspectionReadings entities 
    where location == location 
    sort date descending 
    return the top Entity details} 
add the Location details and the InspectionReading details into a new table 
return new table 

результат должен быть DataGrid со списком мест и их последней даты считывания инспекции. каждое место должно появляться только один раз.

Что мне удалось это (это в моем DomainService.cs)

 public IQueryable<LocationStatusList> GetLocationStatus() 
     { 
     var status = (from a in ObjectContext.Locations 
         from b in ObjectContext.InspectionReadings 
         orderby b.DateTaken descending, a.Name 
         select new LocationStatusList() 
         { 
          ID = b.ID, 
          LocationName = a.Name, 
          LastInspectionDate = b.DateTaken ?? DateTime.MinValue, // the data is nullable so it needs a value to return in that case 
          StatusNumber = b.Status ?? -1 // the data is nullable so it needs a value to return in that case 
         }); 
     return status; 
     } 

, которая возвращает весь InspectionItems объекты с их соответствующим местом и хотя я пытался, я не могу найти способ сделать Что мне нужно.

Я хотел бы сделать весь код для этого в классе DomainService, но единственный способ, который я могу представить на данный момент, - дать запрос каждому имени местоположения в качестве параметра из viewmodel, вернуть единый объект и создать новый список и добавить каждый отдельный объект.

Несомненно, это может быть сделано в запросе LINQ?

ответ

1

Окончательный вариант, если я правильно:

var status = (from a in ObjectContext.Locations 
       select new {Location = a, LastReading = a.Inspections.SelectMany(i=>i.InspectionReadings).OrderBy(r=>r.PostDate).FirstOrDefault()}; 
+0

Спасибо! Я вижу, как это будет работать, к сожалению, моя таблица InspectionReadings не является прямым дочерним элементом моей таблицы Inspections, поэтому она вызывает ошибку .SelectMany, поскольку она не может найти ключевое отношение. У InspectionReadings есть InspectionItemsID, ​​ У InspectionItems есть InspectionID, , поэтому в иерархии есть дополнительный уровень. мне нужно что-то вроде: LastReading = a.Inspections.SelectMany (я => i.InspectionItems.SelectMany (J => j.InspectionReadings) .OrderBy (г => r.DateTaken) .FirstOrDefault()) Вы можете помочь? – xhedgepigx

+0

Я думаю, что это должно сработать. –

+0

Он выдает ошибку «Аргументы типа для метода» System.Linq.Enumerable.SelectMany (System.Collections.Generic.IEnumerable , System.Func >) 'не может быть выведено из использования. Попробуйте явно указать аргументы типа. – xhedgepigx

0

Ok попробовать это:

var result = from l in Locations 
     from i in l.Inspestions 
     from ii in i.InspestionItems 
     from ir in ii.InspectionReadings 
     group ir by l into g 
     select new {Location = g.Key, LastReading = g.OrderBy(r=>r.DateTaken).LastOrDefault() }; 

Последний или по умолчанию по той причине, что порядок сортировки по умолчанию является восходящим, и вам нужно самым последним (последнее).

0

Спасибо @Val, код теперь у меня есть это:

public IQueryable<LocationStatusList> GetLocationStatus() 
{ 
    var status = (from a in ObjectContext.Locations 
       select new LocationStatusList 
       { 
        ID=a.ID, 
        Name=a.Name, 
        LastInspectionDate= (from b in ObjectContext.Inspections 
             from c in ObjectContext.InspectionReadings 
             where c.InspectionItemID==b.ID && b.LocationID==a.ID 
             orderby c.DateTaken descending 
             select c.DateTaken).FirstOrDefault()??DateTime.MinValue, 


        StatusNumber = (from b in ObjectContext.Inspections 
            from c in ObjectContext.InspectionReadings 
            where c.InspectionItemID==b.ID && b.LocationID==a.ID 
            orderby c.DateTaken descending 
            select c.Status).FirstOrDefault()??-1, 
       }); 
    return status; 
} 

, который дает именно то, что мне нужно. Спасибо!