LINQ для возвращения первым в повторяющихся последовательностях - PullRequest
0 голосов
/ 06 марта 2011

У меня есть таблица измерений следующим образом:
SourceId: int
Метка времени: дата / время
Измерение: int

Пример данных выглядит следующим образом (подробнее о звездочках ниже):
SID | TimeStamp | Измерение
10 | 02-01-2011 12:00:00 | 30 *
10 | 02-01-2011 12:10:00 | 30
10 | 02-01-2011 12:17:00 | 32 *
10 | 02-01-2011 12:29:00 | 30 *
10 | 02-01-2011 12:34:00 | 30
10 | 02-01-2011 12:39:00 | 35 *
10 | 02-01-2011 12:46:00 | 36 *
10 | 02-01-2011 12:39:00 | 36
10 | 02-01-2011 12:54:00 | 36
11 | 02-01-2011 12:00:00 | 36 *
11 | 02-01-2011 12:10:00 | 36
11 | 02-01-2011 12:17:00 | 37 *
11 | 02-01-2011 12:29:00 | 38 *
11 | 02-01-2011 12:34:00 | 38
11 | 02-01-2011 12:39:00 | 37 *
11 | 02-01-2011 12:46:00 | 36 *
11 | 02-01-2011 12:39:00 | 36
11 | 02-01-2011 12:54:00 | 36

Мне нужен запрос LINQ, который будет возвращать только те строки, когда значение Measurement отличается от предыдущей строки с тем же SourceId (т. Е. Каждая строка отмечена звездочкой). Таблица должна быть отсортирована по SourceId, а затем по TimeStamp.

Данные из запроса будут использоваться для построения графика, где каждый SourceId является серией. Исходная таблица содержит несколько миллионов строк, а повторяющиеся измерения исчисляются тысячами. Поскольку эти повторяющиеся значения измерений не имеют никакого значения для результирующего графика, я бы хотел их исключить перед передачей данных в мой граф для управления рендерингом.

Я пытался использовать Distinct () различными способами и рассмотрел совокупные запросы здесь http://msdn.microsoft.com/en-us/vcsharp/aa336746, но не вижу очевидного решения.

Ответы [ 3 ]

0 голосов
/ 06 марта 2011

Иногда достаточно простого старого цикла foreach.

var finalList = new List<MyRowObject>();
MyRowObject prevRow = null;

foreach (var row in myCollection)
{
    if (prevRow == null || (row.SID != prevRow.SID || row.Measurement != prevRow.Measurement))
    {
        finalList.Add(row);
    }
    prevRow = row;
}
0 голосов
/ 06 марта 2011

Нет способа сделать это в одном запросе в sql.Поэтому нет возможности сделать это в одном запросе в linq to sql.

Проблема в том, что вам нужно сравнить каждую строку со «следующей» строкой.Это просто не то, что sql делает хорошо.

Посмотрите на первые пять строк:

10 | 02-01-2011 12:00:00 | 30 *
10 | 02-01-2011 12:10:00 | 30
10 | 02-01-2011 12:17:00 | 32 *
10 | 02-01-2011 12:29:00 | 30 *
10 | 02-01-2011 12:34:00 | 30

Вы хотите сохранить 2 записи с 30 и удалить 2 записи с 30. Это правилавне группировки.

0 голосов
/ 06 марта 2011

Лично мне нравится метод расширения DistinctUntilChanged, который включен в библиотеку расширений Rx.Это очень удобно.Кстати, как и остальная часть библиотеки.

Но я понимаю, что вы, возможно, не захотите добавлять совершенно новую зависимость только для этого.В этом случае я предлагаю Zip:

        sequence.Take(1).Concat(
        sequence.Zip( sequence.Skip(1), (prev,next) => new { item = next, sameAsPrevious = prev == next } )
            .Where( (x,index) => !x.sameAsPrevious )
            .Select( x => x.item )
        )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...