Вычисление разности между разными столбцами в разных строках

у меня есть таблица, которая записывает, что происходит с автомобилем во время посещения. Для каждого визита есть несколько строк, чтобы обозначить, что было сделано. Стол выглядит так

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

Я хочу построить запрос LINQ, способный получить количество времени, которое заняло посещение. TotalTime рассчитывается путем нахождения первого и последнего (наименьшего и наибольшего) ActionID, потом last.EndTime - first.StartTime. Ожидаемые результаты:

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

Я могу генерировать ожидаемые результаты делать

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});

мне действительно не нравится хак, который я использовал, чтобы получить последний ActionID, и я бы очень хотел иметь возможность сделать это в 1 заявлении LINQ. Что мне нужно сделать, чтобы достичь этого?

2 ответов


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

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: это предполагает, что actionid не имеет значения, как максимальные и минимальные даты начала. Вот другое решение, в котором actionid упорядочены, а первый и последний визиты используются для расчета разницы во времени.

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
                    });

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() });

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