2013-03-04 22 views
7

Ho una tabella che registra cosa succede a un veicolo durante una visita. Per ogni visita, ci sono più righe per indicare cosa è stato fatto. La tabella è simile al seguenteCalcolo della differenza tra diverse colonne in diverse file

VisitID | ActionID | StartTime | EndTime 
    0 | 0  | 1/1/2013 | 1/2/2013 
    1 | 0  | 1/2/2013 | 1/4/2013 
    1 | 1  | 1/4/2013 | 1/7/2013 
    2 | 0  | 1/4/2013 | 1/5/2013 
    2 | 1  | 1/5/2013 | 1/6/2013 
    2 | 2  | 1/6/2013 | 1/7/2013 

Desidero creare una query LINQ in grado di ottenere il tempo richiesto da una visita. TotalTime viene calcolato trovando prima il primo e l'ultimo (minimo e massimo) ActionID, quindi last.EndTime - first.StartTime. Risultati attesi:

VisitID | TotalTime 
    0 | 1 
    1 | 5 
    2 | 3 

posso generare i miei risultati attesi facendo

var first = db.Visits.Where(v => v.ActionID == 0) 
var last = db.Visits.GroupBy(x => x.VisitID).Select(g => g.OrderByDescending(x => x.ActionID).First()) 

first.Join(last, f => f.VisitID, l => l.VisitID, (f, l) new{ VisitID = Key, TotalTime = l.EndTime - f.StartTime}); 

Io davvero non mi piace l'hack ho usato per ottenere l'ultimo ActionID, e mi piacerebbe davvero essere in grado di fallo entro 1 istruzione LINQ. Cosa devo fare per raggiungere questo obiettivo?

risposta

4

Penso che questo dovrebbe funzionare ...

var result = db.Visits.GroupBy(v => v.VisitID) 
      .Select(g => new 
        { 
         VisitId = g.Key, 
         TotalTime = g.Max(v => v.EndTime).Subtract(g.Min(v => v.StartTime)).Days 
        }); 

Edit: Questo presuppone l'ActionID non importa tanto come il massimo e minimo date di inizio. Ecco una soluzione diversa in cui sono ordinati gli actionid e vengono utilizzate la prima e l'ultima visita per calcolare la differenza di orario.

var result2 = db.Visits.GroupBy(v => v.VisitID) 
      .Select(g => new 
        { 
         VisitId = g.Key, 
         TotalTime = 
        g.OrderBy(v => v.ActionID).Last().EndTime.Subtract(g.OrderBy(v => v.ActionID).First().StartTime).Days 
        }); 
+1

+1 Anche io penso che lui vuole totaldays, non intero intervallo –

+1

@lazyberezovsky Buona cattura. Ho aggiornato la risposta per restituire il numero di giorni. Tuttavia, non sono sicuro che questa query funzionerà con Entity Framework, in quanto sembra una query EF. –

+1

Ovviamente! Raggruppa per VisitID e usa 'min' e' max'. Brownie punta a fornire entrambe le risposte a una domanda possibilmente ambigua – Jeff

0
db.Visits.GroupBy(v => v.VisitID) 
    .Select(g => new { VisitId = g.Key, 
      Days = g.Select(x => x.EndTime.ToOADate()).Sum() 
      -g.Select(x => x.StartTime.ToOADate()).Sum() }); 

usato un piccolo hack per aggiungere tutti comincia giorni e giorni finali per ogni visita e ottenere la differenza.

Problemi correlati