dotnet / dotnet/efcore

EF Core 8 & 9 throw when "external" sets of primitive types are included in select

Open
#35,568 2 comments 0 reactions 0 assignees View on GitHub
area-query customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

### Bug description

I also noticed that when a variable that is a `HashSet` (for example) is included in the select expression, EF Core 8 & 9 throw errors that seem to be JSON-serialization related. Like in #35567, this issue doesn't seem to occur when a non-primitive variable is included in the select expression.

Please refer to the reproduction and the stack trace included below 🙂.

- EF core 7.0.20 runs the queries with no errors.

![](https://github.com/user-attachments/assets/ebb1900d-052e-4967-b841-553cd52b110c)

- EF core 8.0.12 & 9.0.1 throw as described.

![](https://github.com/user-attachments/assets/ca6c0b6d-98d6-4ab3-a047-f51f144aa6d0)

### Your code

```csharp
public class Program
{
public static async Task Main()
{
var db = new Db();
var listOfInt = new List { 1 };
var setOfDouble = new HashSet { 1d };
var anObject = new { };

Write($"EF Core {typeof(DbContext).Assembly.GetName().Version}");

Write("\n1. SELECT e.Id, listOfInt");
await db.Entities.Select((e) => new { e.Id, listOfInt }).ToListAsync();

Write("\n2. SELECT e.Id, setOfInt");
try { await db.Entities.Select((e) => new { e.Id, setOfDouble }).ToListAsync(); }
catch (Exception e) { Console.WriteLine(e); }

Write("\n3. SELECT e.Id, listOfInt, setOfInt");
try { await db.Entities.Select((e) => new { e.Id, listOfInt, setOfDouble }).ToListAsync(); }
catch (Exception e) { Console.WriteLine(e); }

Write("\n4. SELECT e.Id, listOfInt, setOfInt, anObject");
try { await db.Entities.Select((e) => new { e.Id, listOfInt, setOfDouble, anObject }).ToListAsync(); }
catch (Exception e) { Console.WriteLine(e); }
}

public class Db : DbContext
{
public DbSet Entities { get; init; } = null!;

protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlServer("...");
options.LogTo(Console.WriteLine, LogLevel.Information);
}
}

[Table("entity")]
[PrimaryKey(nameof(Id))]
public class Entity
{
[Column("id")]
public required int Id { get; set; }
}

public static void Write(string s)
{
var c = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine(s);
Console.ForegroundColor = c;
}
}
```

### Stack traces

With `setOfDouble` as a `HashSet`, the stack trace is:

```
An exception occurred while iterating over the results of a query for context type 'TestEfCore.Program+Db'.
System.InvalidCastException: Unable to cast object of type 'System.Collections.Generic.HashSet`1[System.Double]' to type 'System.Collections.Generic.IList`1[System.Double]'.
at Microsoft.EntityFrameworkCore.Storage.Json.JsonCollectionOfStructsReaderWriter`2.FromJsonTyped(Utf8JsonReaderManager& manager, Object existingObject)
at Microsoft.EntityFrameworkCore.Storage.Json.JsonValueReaderWriter`1.FromJson(Utf8JsonReaderManager& manager, Object existingObject)
at Microsoft.EntityFrameworkCore.Storage.Json.JsonValueReaderWriter.FromJsonString(String json, Object existingObject)
at lambda_method11(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at TestEfCore.Program.Main() in ~\Projects\TestWeb\TestEfCore\Program.cs:line 27
```

As an `IReadOnlySet` instead:

```
An exception occurred while iterating over the results of a query for context type 'TestEfCore.Program+Db'.
System.MissingMethodException: Cannot dynamically create an instance of type 'System.Collections.Generic.IReadOnlySet`1[System.Double]'. Reason: Cannot create an instance of an interface.
at System.RuntimeType.ActivatorCache..ctor(RuntimeType rt)
at System.RuntimeType.ActivatorCache.Create(RuntimeType type)
at System.RuntimeType.IGenericCacheEntry`1.CreateAndCache(RuntimeType type)
at System.RuntimeType.CreateInstanceOfT()
at System.Activator.CreateInstance[T]()
at Microsoft.EntityFrameworkCore.Storage.Json.JsonCollectionOfStructsReaderWriter`2.FromJsonTyped(Utf8JsonReaderManager& manager, Object existingObject)
at Microsoft.EntityFrameworkCore.Storage.Json.JsonValueReaderWriter`1.FromJson(Utf8JsonReaderManager& manager, Object existingObject)
at Microsoft.EntityFrameworkCore.Storage.Json.JsonValueReaderWriter.FromJsonString(String json, Object existingObject)
at lambda_method11(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at TestEfCore.Program.Main() in ~\Projects\TestWeb\TestEfCore\Program.cs:line 27
```

### Verbose output

```text

```

### EF Core version

9.0.1

### Database provider

Microsoft.EntityFrameworkCore.SqlServer

### Target framework

.NET 9.0.102

### Operating system

Windows 11

### IDE

Microsoft Visual Studio Professional 2022 x64 17.12.4

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.