简体   繁体   中英

EntityFramework Core Group By with Sum

Haven't written any code in a while and I'm trying to shake the rust off by writing a small app for my kids to track the books they've read over the summer. The DB is simple, only 3 tables. 1 for books (title, author, pages etc), 1 for reader names and 1 is the actual reading log (1 row for each book they read, foreign key relationship to book table and reader table).

Trying to use EntityFramework core to write a query that will return the total pages read by reader. I can run this in SSMS and it works fine

select r.Name, sum(b.Pages) as PagesRead
from ReadingLog rl
inner join Readers r on rl.ReaderId = r.Id
inner join Books b on rl.BookId = b.Id
where rl.IsActive = 1
group by r.Name

I tried writing it in EF as this:

var pagesByReader = _context.ReadingLog
                            .Where(m => m.IsActive)
                            .GroupBy(m => m.Reader.Name)
                            .Select(m => new GraphViewModel()
                                   {
                                      Reader = m.Key,
                                      PagesRead = m.Sum(b => b.Book.Pages)
                                   })
                            .ToList();

but I get this error at runtime: ).Book.Pages' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync()

I think I'm just writing the EF query wrong but I can't figure out why. Any help is appreciated

Looks like you have m.Key in the select . When using GroupBy , all values in a select that are not defined in the group by must be in an aggregate function.

Try changing m.Key to m.Key.First()

As mentioned in the comment, the sql is tranlated to Linq, like the following code:

var result = (from rl in _context.ReadingLog 
            join r in _context.Readers on rl.ReaderId equals r.Id 
            join b in _context.Books on rl.BookId equals b.Id 
            where rl.IsActive 
            group new {r,b} by r.Name int g 
            select 
            new GraphViewModel 
            { 
                Reader = g.Key, 
                PagesRead = g.Sum(x => x.b.Pages) 
            }).ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM