EF Core: асинхронный вложенный выбор в IGrouping, вызывающий ArgumentException - PullRequest
0 голосов
/ 15 ноября 2018

Обновлено с другими соответствующими классами

public class TrendItem
{
    public string ItemTitle { get; set; }

    public IEnumerable<string> ItemValues { get; set; }
}

public class TrendValue
{
    public int Id { get; set; }

    public TrendResultType TrendType { get; set; }

    public string Value { get; set; }

    public Trend Trend { get; set; } // contains DateRecorded property
}

См. Ниже функцию, которая использует EF Core (2.1):

    public async Task<List<TrendItem>> GetTrends(
        int companyId,
        TrendResultType type,
        DateTimeOffset startDate,
        DateTimeOffset endDate,
        RatingResultGroup group
    )
    {
        var data = _dataContext.TrendValues.Where(rr =>
                        rr.Trend.CompanyId == companyId &&
                        rr.TrendType == type &&
                        rr.Trend.DateRecorded >= startDate &&
                        rr.Trend.DateRecorded <= endDate);

        return await data.GroupBy(rr => new { rr.Trend.DateRecorded.Year, rr.Trend.DateRecorded.Month })
                         .Select(g => new TrendItem() { ItemTitle = $"{g.Key.Year}-{g.Key.Month}", ItemValues = g.Select(rr => rr.Value) })
                         .ToListAsync();
    }

У меня проблемы, особенно с частью g.Select (rr => rr.Value) , где я намеревался выбрать коллекцию значений (строк).

Всякий раз, когда я пытаюсь изменить это на что-то другое, например g.Sum (rr => int.Parse (rr.Value)) , оно работает нормально. Кажется, это проблема с поиском коллекции.

Я всегда получаю ArgumentException: типы аргументов не совпадают .

Это связано с асинхронной функцией?

1 Ответ

0 голосов
/ 16 ноября 2018

Хм, я бы начал с поиска упрощенного извлечения данных в анонимный тип для выполнения группировки, а затем преобразования в модель представления.Возможно, EF немного запуталась, работая со значениями сгруппированных элементов.

Похоже, вы хотите сгруппировать по дате (год-месяц), а затем получить список значений в каждой группе:

var query = _dataContext.TrendValues
              .Where(rr =>
                rr.Trend.CompanyId == companyId 
                && rr.TrendType == type 
                && rr.Trend.DateRecorded >= startDate 
                && rr.Trend.DateRecorded <= endDate)
              .Select(rr => new 
              { 
                TrendYear = rr.Trend.DateRecorded.Year,
                TrendMonth = rr.Trend.DateRecorded.Month,
                rr.Value
              }).ToListAsync();

var data = query.GroupBy(rr => new { rr.TrendYear, rr.TrendMonth })
            .Select(g => new TrendItem() { ItemTitle = $"{g.Key.Year}-{g.Key.Month}", ItemValues = g.ToList().Select(rr => rr.Value).ToList() })
            .ToList();
return data;

, что можно упростить до:

var query = _dataContext.TrendValues
             .Where(rr =>
               rr.Trend.CompanyId == companyId &&
               rr.TrendType == type &&
               rr.Trend.DateRecorded >= startDate &&
               rr.Trend.DateRecorded <= endDate)
               .Select(rr => new 
               { 
                 TrendDate = rr.Trend.DateRecorded.Year + "-" + rr.Trend.DateRecorded.Month,
                 rr.Value
               }).ToListAsync();

var data = query.GroupBy(rr => rr.TrendDate)
             .Select(g => new TrendItem() { ItemTitle = $"{g.Key}", ItemValues = g.ToList().Select(rr => rr.Value).ToList() })
             .ToList();
return data;

. Для выбора TrendDate в запросе может потребоваться некоторая работа, если Trend.Year и Trend.Month являются числовыми полями.

...