dotnet / dotnet/efcore

[EF Core 8.x] - Primitive Collections doesn't work with ICollection, while querying data.

Open
#35,502 9 comments 3 reactions 0 assignees View on GitHub
area-primitive-collections area-query customer-reported needs-design
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

### Bug description

Primitive Collections doesn't work with ICollection, while querying data.

According to [this](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-8.0/whatsnew#primitive-collections:~:text=public%20ICollection%3Cstring%3E%20Strings%20%7B%20get%3B%20set%3B%20%7D) example it should work.

Note: IList, List and T[] works.

[EFCoreICollectionBug.zip](https://github.com/user-attachments/files/18478493/EFCoreICollectionBug.zip)

### Your code

```csharp
// See https://aka.ms/new-console-template for more information

using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;

var connection = new SqliteConnection("DataSource=:memory:");
connection.Open();
var context = new ApplicationDbContext(new DbContextOptionsBuilder()
.UseSqlite(connection)
.Options);
context.Database.EnsureCreated();

var myDataWithList = new MyModelWithList
{
MyEnums = new List { MyEnum.Test1, MyEnum.Test2 }
};

context.MyModelWithLists.Add(myDataWithList);
await context.SaveChangesAsync();
context.ChangeTracker.Clear();

var dataWithList = await context.MyModelWithLists.FirstAsync(); // no error

// ERORR BELOW

var myData = new MyModel
{
MyEnums = new List { MyEnum.Test1, MyEnum.Test2 }
};

context.MyModels.Add(myData);
await context.SaveChangesAsync();
context.ChangeTracker.Clear();

var data = await context.MyModels.FirstAsync(); // error here

// CLASS DEFINITIONS
public enum MyEnum
{
Test1,
Test2,
Test3
}

public class MyModel
{
public Guid Id { get; set; }
public ICollection MyEnums { get; set; } = [];
}

public class MyModelWithList
{
public Guid Id { get; set; }
public List MyEnums { get; set; } = [];
}

public sealed class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions options) : base(options)
{
}

public DbSet MyModels { get; set; } = null!;
public DbSet MyModelWithLists { get; set; } = null!;

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity()
.HasKey(x => x.Id);

modelBuilder.Entity()
.Property(x => x.MyEnums)
.HasMaxLength(1024);

modelBuilder.Entity()
.HasKey(x => x.Id);

modelBuilder.Entity()
.Property(x => x.MyEnums)
.HasMaxLength(1024);
}
}
```

### Stack traces

```text
Unhandled exception. System.ArgumentException: Expression of type 'System.Collections.Generic.ICollection`1[EFCoreICollectionBug.MyEnum]' cannot be used for parameter of type 'System.Collections.Generic.IList`1[EFCoreICollectionBug.MyEnum]' of method 'System.Collections.Generic.IList`1[EFCoreICollectionBug.MyEnum] PopulateList[MyEnum](System.Collections.Generic.IList`1[EFCoreICollectionBug.MyEnum], System.Collections.Generic.IList`1[EFCoreICollectionBug.MyEnum])' (Parameter 'arg0')
at System.Dynamic.Utils.ExpressionUtils.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arguments, ParameterInfo pi, String methodParamName, String argumentParamName, Int32 index)
at System.Linq.Expressions.Expression.Call(MethodInfo method, Expression arg0, Expression arg1)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityMaterializerSource.g__CreateMemberAssignment|14_0(Expression parameter, MemberInfo memberInfo, IPropertyBase property, Expression value)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityMaterializerSource.AddInitializeExpressions(HashSet`1 properties, ParameterBindingInfo bindingInfo, Expression instanceVariable, List`1 blockExpressions)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityMaterializerSource.CreateMaterializeExpression(List`1 blockExpressions, ParameterExpression instanceVariable, Expression constructorExpression, HashSet`1 properties, ParameterBindingInfo bindingInfo)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityMaterializerSource.CreateMaterializeExpression(EntityMaterializerSourceParameters parameters, Expression materializationContextExpression)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.EntityMaterializerInjectingExpressionVisitor.CreateFullMaterializeExpression(ITypeBase concreteTypeBase, ValueTuple`4 materializeExpressionContext)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.EntityMaterializerInjectingExpressionVisitor.MaterializeEntity(StructuralTypeShaperExpression shaper, ParameterExpression materializationContextVariable, ParameterExpression concreteEntityTypeVariable, ParameterExpression instanceVariable, ParameterExpression entryVariable)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.EntityMaterializerInjectingExpressionVisitor.ProcessEntityShaper(StructuralTypeShaperExpression shaper)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.EntityMaterializerInjectingExpressionVisitor.VisitExtension(Expression extensionExpression)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.EntityMaterializerInjectingExpressionVisitor.Inject(Expression expression)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.InjectEntityMaterializers(Expression expression)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.VisitExtension(Expression extensionExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.ProcessShaper(Expression shaperExpression, RelationalCommandCache& relationalCommandCache, IReadOnlyList`1& readerColumns, LambdaExpression& relatedDataLoaders, Int32& collectionId)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.VisitShapedQuery(ShapedQueryExpression shapedQueryExpression)
at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.VisitExtension(Expression extensionExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.VisitExtension(Expression extensionExpression)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0`1.b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.FirstAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at Program.$(String[] args) in D:\Projekty\EFCoreICollectionBug\EFCoreICollectionBug\Program.cs:line 38
at Program.(String[] args)
```

### Verbose output

```text

```

### EF Core version

8.0.6

### Database provider

Microsoft.EntityFrameworkCore.Sqlite

### Target framework

.Net 8

### Operating system

Windows 11

### IDE

Rider 2024

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.