Как я могу заставить пользователей группировать его по времени в IQueryable?

у меня есть этот запрос

var creature = await _context.Data
                             .Where(x => x.Id.Contains("mono"))
                             .GroupBy(group => new
                                               {   
                                                    month = group.Time.Month,
                                                    year = group.Time.Year,
                                               })
                             .Select(data => new 
                                             {
                                                 data.Key.month,
                                                 data.Key.year,
                                                 User = data.Select(x => x.User.Distinct().Count())
                                             })
                             .ToListAsync()

Мне нужно четко определить количество пользователей и сгруппировать их по месяцам и годам.

Но получаю ошибку, что запрос не читается и не могу его перевести!

Что я должен изменить здесь?


person Aziz Alzayed    schedule 07.05.2021    source источник
comment
Что является основным хранилищем данных здесь? это РСУБД (т.е. база данных)? Если так: честно, в тот момент, когда LINQ начинает бороться с вами: просто напишите SQL - его будет проще поддерживать, он даст вам правильный результат и он будет более эффективным (a: потому что нет шага понимания запроса , и b: потому что написанный вручную SQL обычно намного лучше машинного SQL)   -  person Marc Gravell    schedule 07.05.2021
comment
Какую версию EF Core вы используете? Я умею писать такой запрос только на 5+   -  person Svyatoslav Danyliv    schedule 07.05.2021
comment
EF 3.1 и данные из базы данных   -  person Aziz Alzayed    schedule 07.05.2021
comment
Технически это дубликат stackoverflow.com/questions/56803706/. К сожалению, решение там не работает для v3.x, и у меня нет времени его обновлять, да и стоит оно вообще, так как оно уже реализовано в 5.x. Так может быть, хорошее время для обновления? Если вы не используете NET Framework, это не должно быть проблемой (по сравнению, например, с 2.x до 3.x из-за большого количества критических изменений).   -  person Ivan Stoev    schedule 09.05.2021


Ответы (1)


Честно говоря, иногда лучший способ написать выражение IQueryable<T> это: not to; это похоже _context здесь контекст БД, больше всего похожий на Entity Framework. Если это так: просто используйте SQL (точный API для этого зависит от вашей версии EF и/или от того, хотите ли вы вместо этого использовать что-то вроде Dapper, что может быть полезно, когда запрос не требует ввода ORM); SQL будет примерно таким:

select  DATEPART(year, yt.Time) as [Year],
        DATEPART(month, yt.Time) as [Month],
        COUNT(DISTINCT yt.UserId) as [Users]
from YourTable yt
where yt.Id like '%mono%'
group by DATEPART(year, yt.Time), DATEPART(month, yt.Time)
order by DATEPART(year, yt.Time), DATEPART(month, yt.Time);
person Marc Gravell    schedule 07.05.2021