dotnet / dotnet/efcore

EF7 - GroupBy resulting in ArgumentNullException - Value cannot be null. (Parameter 'collection');

Open
#31,388 4 comments 8 reactions 0 assignees View on GitHub
area-groupby area-query customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

Working on a conversion from Framework EF6 to Core EF7. This code previously was working without error.
Converting from net framework over to core, and that comes with moving Entity Framework 6 over to EFCore 7.

I have a keyless View configured:

```
modelBuilder.Entity(entity =>
{
entity
.HasNoKey()
.ToView("MySampleView");
```

My query is simple and previously worked fine with EF6 under Framework. Filter, Group, ToDictionary

```
var result = await context.MySampleView
.Where(x => ... SomeConditions)
.GroupBy(x => new { x.Column1, x.Column2, x.Column3 })
.ToDictionaryAsync(x => x.Key.Column1,
x => new { x.Key.Column2, x.Key.Column3, ... });
```
*Note - there will not be a duplicate key here - Column1,2,3 are always the same*

However, this will throw an exception that comes from within the EF7 framework.

`Value cannot be null. (Parameter 'collection')`

Stack trace put this inside the EFCore source:

```
System.ArgumentNullException
HResult=0x80004003
Message=Value cannot be null. (Parameter 'collection')
Source=System.Private.CoreLib
StackTrace:
at System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument) in /_/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs:line 284
```

*Apologize for the screenshots here, as I can't seem get the full Stack Trace from VS in text format for some reason.*

[![Stack Trace View][1]][1]

Digging through the symbol source, I can see where this is happening, but it shouldn't be happening.

You can see it passing this nullable `_preGroupByIdentifier` into it. In this case, null. (this is MS Symbol Source)
[![From the stack, this is responsible for the variable][2]][2]
MS Ref Source: [SelectExpression ref 1][3]

I validated that it should NOT be null, but this is tricky. I am not sure if there is some optimizer issue or just my debugger is lying to me here. the `_preGroupByIdentifier` should be set to an empty list here, but it's totally skipped as shown here. This is from the MS Symbol Source - Note, for other queries, I have seen it not skip that second breakpoint. What is going on with this? *I don't think this error would be happening if this was not skipped over!*

Animated GIF revealing _preGroupByIdentifier not being set:

[![_preGroupByIdentifier not being set inside if statement][4]][4]
MS Ref Source: [SelectExpression ref 2][5]

As a work around, this works and no errors, but puts the GroupBy/Dictionary into the standard Linq/Entities. This is not the right way to do it, as the projection should be handled by the SQL server + EF, not shaped in memory in the dotnet app.

```
var result = (await context.MySampleView
.Where(x => ... SomeConditions)

.ToListAsync()) // Running the ToListAsync first - not desirable

.GroupBy(x => new { x.Column1, x.Column2, x.Column3 })
.ToDictionaryAsync(x => x.Key.Column1,
x => new { x.Key.Column2, x.Key.Column3 });
```

Help me find what I am missing here.

[1]: https://i.stack.imgur.com/xUa04.png
[2]: https://i.stack.imgur.com/BeyVa.png
[3]: https://github.com/dotnet/efcore/blob/82e96d9eb550125d18e4f456a7ff80f1fb292a43/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs#L914
[4]: https://i.stack.imgur.com/LUOhp.gif
[5]: https://github.com/dotnet/efcore/blob/82e96d9eb550125d18e4f456a7ff80f1fb292a43/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs#L1985

EF Core version: 7
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 7.0
Operating system: Win11 (dev)
IDE: Visual Studio 2022 17.6

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.