[EF Core 8.x] - Primitive Collections doesn't work with ICollection, while querying data. #35502
Open
Description
Bug description
Primitive Collections doesn't work with ICollection, while querying data.
According to this example it should work.
Note: IList, List and T[] works.
Your code
// 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<ApplicationDbContext>()
.UseSqlite(connection)
.Options);
context.Database.EnsureCreated();
var myDataWithList = new MyModelWithList
{
MyEnums = new List<MyEnum> { 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> { 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<MyEnum> MyEnums { get; set; } = [];
}
public class MyModelWithList
{
public Guid Id { get; set; }
public List<MyEnum> MyEnums { get; set; } = [];
}
public sealed class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
public DbSet<MyModel> MyModels { get; set; } = null!;
public DbSet<MyModelWithList> MyModelWithLists { get; set; } = null!;
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyModel>()
.HasKey(x => x.Id);
modelBuilder.Entity<MyModel>()
.Property(x => x.MyEnums)
.HasMaxLength(1024);
modelBuilder.Entity<MyModelWithList>()
.HasKey(x => x.Id);
modelBuilder.Entity<MyModelWithList>()
.Property(x => x.MyEnums)
.HasMaxLength(1024);
}
}
Stack traces
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.<AddInitializeExpressions>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.<ExecuteAsync>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.<Main>$(String[] args) in D:\Projekty\EFCoreICollectionBug\EFCoreICollectionBug\Program.cs:line 38
at Program.<Main>(String[] args)
Verbose output
EF Core version
8.0.6
Database provider
Microsoft.EntityFrameworkCore.Sqlite
Target framework
.Net 8
Operating system
Windows 11
IDE
Rider 2024