Заполнение недостающих дат с помощью linq группы запросом даты

Удостоверьтесь, что Ваши страницы поддерживают Измененный в последний раз & If-Modified-Since и/или Завершающий тег & заголовки If-None-Match. С ними можно избежать многих вычислений и передач полностью.

Поиск условного выражения HTTP ДОБИРАЮТСЯ для получения дополнительной информации.

8
задан Greg Roberts 23 September 2009 в 21:35
поделиться

3 ответа

Я только что сделал это сегодня. Я собрал полные данные из базы данных, а затем создал «образец пустой» таблицы. Наконец, я произвел внешнее соединение пустой таблицы с реальными данными и использовал конструкцию DefaultIfEmpty (), чтобы узнать, когда в базе данных отсутствовала строка, чтобы заполнить ее значениями по умолчанию.

Вот мой код:

int days = 30;

// Gather the data we have in the database, which will be incomplete for the graph (i.e. missing dates/subsystems).
var dataQuery =
    from tr in SourceDataTable
    where (DateTime.UtcNow - tr.CreatedTime).Days < 30
    group tr by new { tr.CreatedTime.Date, tr.Subsystem } into g
    orderby g.Key.Date ascending, g.Key.SubSystem ascending
    select new MyResults()
    {
        Date = g.Key.Date, 
        SubSystem = g.Key.SubSystem,
        Count = g.Count()
    };

// Generate the list of subsystems we want.
var subsystems = new[] { SubSystem.Foo, SubSystem.Bar }.AsQueryable();

// Generate the list of Dates we want.
var datetimes = new List<DateTime>();
for (int i = 0; i < days; i++)
{
    datetimes.Add(DateTime.UtcNow.AddDays(-i).Date);
}

// Generate the empty table, which is the shape of the output we want but without counts.
var emptyTableQuery =
    from dt in datetimes
    from subsys in subsystems
    select new MyResults()
    {
        Date = dt.Date, 
        SubSystem = subsys,
        Count = 0
    };

// Perform an outer join of the empty table with the real data and use the magic DefaultIfEmpty
// to handle the "there's no data from the database case".
var finalQuery =
    from e in emptyTableQuery
    join realData in dataQuery on 
        new { e.Date, e.SubSystem } equals 
        new { realData.Date, realData.SubSystem } into g
    from realDataJoin in g.DefaultIfEmpty()
    select new MyResults()
    {
        Date = e.Date,
        SubSystem = e.SubSystem,
        Count = realDataJoin == null ? 0 : realDataJoin.Count
    };

return finalQuery.OrderBy(x => x.Date).AsEnumerable();
2
ответ дан 6 December 2019 в 00:58
поделиться

По сути, то, что я в итоге сделал, - это создание списка одного типа со всеми датами в диапазоне и значением 0 для счетчика. Затем объедините результаты моего исходного запроса с этим списком. Основным препятствием было просто создание настраиваемого компаратора IEqualityComparer. Для получения дополнительной информации здесь: щелкните здесь

1
ответ дан 6 December 2019 в 00:58
поделиться

Вы можете сгенерировать список дат, начиная с «начала» и заканчивая «финишем», а затем шаг за шагом проверять количество отсчетов для каждой даты отдельно

0
ответ дан 6 December 2019 в 00:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: