Linq to SQL: получить количество последовательных ежедневных просмотров - PullRequest
4 голосов
/ 10 октября 2010

У меня есть таблица, которая записывает, когда пользователь просматривает страницу. Таблица выглядит примерно так:

ID | Date
1  | 01/01/10 00:00:01.000
2  | 03/01/10 00:00:01.000
3  | 03/01/10 00:00:02.000
4  | 04/01/10 00:00:01.000
5  | 05/01/10 00:00:01.000
6  | 05/01/10 00:00:02.000
7  | 05/01/10 00:00:03.000

Используя Linq-to-SQL, я хочу подсчитать последнюю группу последовательных дней просмотра страницы, но, конечно, я не уверен, как мне поступить. Например, выполнение запроса по указанным выше данным должно вернуть 3.

Любая помощь будет высоко ценится:)

1 Ответ

2 голосов
/ 10 октября 2010

Это данные испытаний. Я добавил 6 октября в конец списка, чтобы убедиться, что результат выбирается только для последней установленной даты.

List<DateTime> viewDates = new List<DateTime>();
viewDates.Add(new DateTime(10, 10, 1));
viewDates.Add(new DateTime(10, 10, 3));
viewDates.Add(new DateTime(10, 10, 3));
viewDates.Add(new DateTime(10, 10, 4));
viewDates.Add(new DateTime(10, 10, 5));
viewDates.Add(new DateTime(10, 10, 5));
viewDates.Add(new DateTime(10, 10, 5));
viewDates.Add(new DateTime(10, 10, 6));



Для начала нам нужно выяснить последнюю последовательную дату:

var lastConsecutiveDate = viewDates
                .Distinct()
                .Reverse()
                .SkipWhile(distinctDate => viewDates.Where(viewDate => (viewDate.Date == distinctDate.Date)).Count() < 2).FirstOrDefault();



У нас есть 2 варианта, чтобы использовать foreach или LINQ? foreach более читабельно по сравнению с LINQ. Я покажу обе реализации.

Это реализация для foreach:

var consecutiveDates = new List<DateTime>();
foreach (var item in viewDates.Where(viewDate => viewDate <= lastConsecutiveDate).Distinct().OrderByDescending(a => a.Date))
{

    //break if datediff is not 1
    int count = consecutiveDates.Count;
    if ((count > 0) && (consecutiveDates[count - 1].Date.AddDays(-1) != item.Date))
    {
        break;
    }

    consecutiveDates.Add(item);
}



Это реализация для LINQ, менее читаемая:

var consecutiveDates = viewDates
    .Where(viewDate => viewDate <= lastConsecutiveDate)
    .Distinct()
    .OrderByDescending(viewDate => viewDate.Date)
    .Aggregate
    (
        new { List = new List<DateTime>() },
        (result, viewDate) =>
        {
            int count = result.List.Count;
            if ((count > 0) && (result.List[count - 1].Date.AddDays(-1) != viewDate.Date))
            {
                return new { result.List };
            }

            result.List.Add(viewDate);
            return new { result.List };
        },
        a => a.List
    );

Console.WriteLine(consecutiveDates.Count()); выведет «3». Я ожидаю больше рефакторинга моего кода, но я ухожу на перерыв.

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