Использование GroupBy DateTime с Entity Framework вызывает исключение - PullRequest
2 голосов
/ 12 июля 2020

Я использую Entity Framework Core версии 3.1.5.

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

"System.InvalidOperationException: выражение LINQ 'DbSet.GroupBy (XXX )}, keySelector: YYY) 'не может быть переведено. Либо перепишите запрос в форме, которая может быть переведена, либо явно переключитесь на оценку клиента, вставив вызов либо AsEnumerable (), AsAsyncEnumerable (), ToList (), либо ToListAsyn c () ".

Примеры кода:

var result = await _tenantDbContext.MetricEntities.GroupBy(o => new { o.MetricType, o.CreatedDate.Value.Year }).Select(g => g.Sum(o => o.Value)).ToListAsync();


var result = await _metricRepository.GetQueryable().GroupBy(metric => DbFunctions.TruncateTime(metric.CreatedDate)).OrderBy(group => group.Key).ToListAsync();


var result = await _metricRepository.GetQueryable().GroupBy(metric => DbFunctions.CreateTime(metric.CreatedDate.Value.Year,null,null)).ToListAsync()


var result = _tenantDbContext.MetricEntities
            .GroupBy(x =>
                SqlFunctions.DateAdd("month", SqlFunctions.DateDiff("month", sqlMinDate, x.CreatedDate),
                    sqlMinDate))
            .Select(x => new
            {
                Period = x.Key // DateTime type
            }).ToListAsync();



var result = await _globalDbContext.MetricEntities.GroupBy(x =>
                new
                {
                    Year = x.CreatedDate.Value.Year
                },
            s => new
            {
                InsertCount = s,
            }
        ).Select(g=>new
        {
            InsertCount = g.Count(),
        }).ToListAsync();

Ссылки:

Entity Framework: эффективная группировка по месяцам

https://atashbahar.com/post/2017-04-27-group-by-day-week-month-quarter-and-year-in-entity-framework

https://entityframework.net/knowledge-base/19225895/linq---grouping-by-date-and-selecting-count

Дополнительные ссылки:

https://www.codeproject.com/Questions/1199021/LINQ-group-by-month-year-and-return-a-sum

Группировка по часам в IQueryable

https://www.mikesdotnetting.com/article/257/entity-framework-recipe-grouping-by-year-and-month

EF Core "Группировать по не может быть переведен и будет оцениваться локально. "

https://entityframeworkcore.com/knowledge-base/58102821/translating-query-with-group-by-and-count-to-linq

https://entityframeworkcore.com/knowledge-base/43728317/linq-group-by-method-not-generating-the-expected-sql

https://www.mikesdotnetting.com/article/257/entity-framework-recipe-grouping-by-year-and-month

Ответы [ 2 ]

0 голосов
/ 12 июля 2020

Единственное, что мне понравилось:

_dbContext.metricEntities.GroupBy(metricEntity =>new
                    {
                        Year = Microsoft.EntityFrameworkCore.EF.Property<DateTime>(metricEntity, "CreatedDate").Date.Year,
                    }
                ).Select(entities =>
                    new MetricGraphNode
                    {
                        X = new DateTime(entities.Key.Year, 1, 1).ToString("yyyy"),
                        Y = entities.Sum(k => k.Value),
                    }).ToList();

Конечно, вы можете добавить месяц, день, час и т. Д. c.

0 голосов
/ 12 июля 2020

Внимательно посмотрите на ошибку, она касается: linq, GroupBy и его селектора, и он сообщает, что он не может быть «переведен».

Вы пытаетесь сделать что-то, что не поддерживается в SQL, скорее всего, вызывает функцию C# в одном из лямбда-выражений. Итак, в основном он говорит: либо измените его, либо сделайте это в памяти.

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

Итак, вместо :

    var restult = db.Table.Where(...).GroupBy(...).ToList();

Попробуйте:

    var restult = db.Table.ToList().Where(...).GroupBy(...);
    //or
    var restult = db.Table.Where(...).ToList().GroupBy(...);
...