1

I upgraded efcore 2.2 to 5 and simple group by is not working,
the data is already in memory, take a look:

List<IGrouping<Categories, Businesses>> businessesByCategory = 
    location.Businesses
            .GroupBy(x => x.Category.Parent ?? x.Category)
            .ToList();

In Ef Core 2.2 it worked fine, the businesses were grouped by their category, now it does nothing.

If I try to group by id it works:

List<IGrouping<int, Businesses>> businessesByCategory = location.Businesses
    .GroupBy(x => x.Category.ParentId ?? x.CategoryId)
   .ToList();

But I need the Category entity and this way I get only the category id.

5
  • No, it didn't work at all. It's actually meaningless as SQL - what would you group by, the table name? EF Core 1 was so restricted it couldn't even handle GroupBy so all the data was loaded on the client and grouped there, without any benefit from indexing. Client-side evaluation was an ugly stop gap measure that was going to be removed. EF Core 2.2. could handle GroupBy but still allowed client side evaluation with warnings. If you checked your application's logs you'd see client-side evaluation warnings. EF Core 3.0 finally disabled client-side evaluation Commented Dec 5, 2020 at 17:32
  • In other words, the code already had a serious performance and logic bug that emitted warnings, while loading the entire table in memory before grouping. EF Core 2.2 warned about it while EF Core 3 finally disabled it Commented Dec 5, 2020 at 17:35
  • 1
    "the data is already in memory" So it's not EF Core (LINQ to Entities), but standard in-memory (LINQ to Objects) GroupBy operation? If yes, probably you have loaded the objects using no tracking query? Commented Dec 5, 2020 at 17:43
  • @IvanStoev you are correct no tracking Commented Dec 5, 2020 at 17:44
  • @IvanStoev Yes, this is LINQ to Objects, it used to work in version 2.2, there is no tracking because it reads the data without modification. Commented Dec 5, 2020 at 17:53

1 Answer 1

3

The issue is caused by EF Core 3.0 no-tracking query behavior breaking change - No-tracking queries no longer perform identity resolution. Because of that, the Category objects with the same Id now are different instances, hence the default equality comparer used by LINQ to Objects GroupBy treats them as different keys, thus not grouping at all.

EF Core 5.0 brings back the 2.x behavior - No-tracking queries with identity resolution, but you must opt-in for it using the AsNoTrackingWithIdentityResolution method in place of AsNoTracking(). Or QueryTrackingBehavior.NoTrackingWithIdentityResolution if setting the default ChangeTracker.QueryTrackingBehavior.

Sign up to request clarification or add additional context in comments.

3 Comments

Useful info! It's maddening, such pivotal behaviors entering, disappearing, entering again. But I'm optimistic about EF core 5 finally having reached a less capricious development path. It's about time...
@Gert My experience with EF started with v6, which seems to have most of the functionality tuned and finalized. But you probably are watching it from the beginning, with all intermediate versions from 1 to 6 I guess, may be it had similar path till get to what it is finally?
Not that long! I started working with it and knowing it when it had raised from the ashes of a burned-down initial version. So, yes, a tentative start back then as well, but as of v. 4 a stable development path with hardly any breaking changes, only useful additions. It's always been a reliable tool, until, yeah, you know.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.