When running the .NET 8 console application below I run into the following exception (thrown at line 10). This exception is thrown when using " 8.0.0-rc.1.23419.6" but works as expected with "7.0.11"
System.ArgumentException
HResult=0x80070057
Message=GenericArguments[1], 'System.Collections.Generic.IEnumerable`1[CaseRecordStaff]', on 'TResult MaterializeJsonEntityCollection[TEntity,TResult](Microsoft.EntityFrameworkCore.Query.QueryContext, System.Object[], Microsoft.EntityFrameworkCore.Storage.Json.JsonReaderData, Microsoft.EntityFrameworkCore.Metadata.INavigationBase, System.Func`4[Microsoft.EntityFrameworkCore.Query.QueryContext,System.Object[],Microsoft.EntityFrameworkCore.Storage.Json.JsonReaderData,TEntity])' violates the constraint of type 'TResult'.
Source=System.Private.CoreLib
StackTrace:
at System.RuntimeType.ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
at System.Reflection.RuntimeMethodInfo.MakeGenericMethod(Type[] methodInstantiation)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.CreateJsonShapers(IEntityType entityType, Boolean nullable, ParameterExpression jsonReaderDataParameter, ParameterExpression keyValuesParameter, Expression parentEntityExpression, INavigation navigation)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.CreateJsonShapers(IEntityType entityType, Boolean nullable, ParameterExpression jsonReaderDataParameter, ParameterExpression keyValuesParameter, Expression parentEntityExpression, INavigation navigation)
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.FirstOrDefaultAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at Program.<<Main>$>d__0.MoveNext() in C:\Users\Nick Shepherd\source\repos\EfCoreJson\EfCoreJson\Program.cs:line 10
This exception was originally thrown at this call stack:
[External Code]
Inner Exception 1:
VerificationException: Method Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor+ShaperProcessingExpressionVisitor.MaterializeJsonEntityCollection: type argument 'System.Collections.Generic.IEnumerable`1[CaseRecordStaff]' violates the constraint of type parameter 'TResult'.
If i change
class CaseRecordLocation
{
private readonly List<CaseRecordStaff> _staff = new();
public IEnumerable<CaseRecordStaff> Staff => _staff.AsReadOnly();
}
to this
class CaseRecordLocation
{
public ICollection<CaseRecordStaff> Staff { get; set; }
}
The code works as expected.
Demo Application:
var dbContextOptionsBuilder = new DbContextOptionsBuilder<DemoDbContext>()
.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=DemoDbContext;Trusted_Connection=True;")
.LogTo(Console.WriteLine, Microsoft.Extensions.Logging.LogLevel.Warning);
var demoDbContext = new DemoDbContext(dbContextOptionsBuilder.Options);
var caseRecord = new CaseRecord();
demoDbContext.CaseRecords.Add(caseRecord);
await demoDbContext.SaveChangesAsync();
caseRecord = await demoDbContext.CaseRecords.Where(cr => cr.Id == 1).FirstOrDefaultAsync();
class CaseRecord
{
public int Id { get; set; }
public CaseRecordLocation? Clinic { get; private set; }
}
class CaseRecordLocation
{
private readonly List<CaseRecordStaff> _staff = new();
public IEnumerable<CaseRecordStaff> Staff => _staff.AsReadOnly();
}
class CaseRecordStaff
{
public string Name { get; set; } = default!;
}
class CaseRecordConfiguration : IEntityTypeConfiguration<CaseRecord>
{
public void Configure(EntityTypeBuilder<CaseRecord> builder)
{
_ = builder.Property(r => r.Id)
.UseIdentityColumn();
_ = builder.OwnsOne(cr => cr.Clinic, ownedNavigationBuilder =>
{
_ = ownedNavigationBuilder.ToJson();
_ = ownedNavigationBuilder.OwnsMany(
tc => tc.Staff);
});
}
}
class DemoDbContext : DbContext
{
public DemoDbContext(DbContextOptions options) : base(options) { }
public DbSet<CaseRecord> CaseRecords => Set<CaseRecord>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
_ = modelBuilder.HasDefaultSchema("mx");
base.OnModelCreating(modelBuilder);
_ = modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
}
}
class DemoDbContextFactory : IDesignTimeDbContextFactory<DemoDbContext>
{
DemoDbContext IDesignTimeDbContextFactory<DemoDbContext>.CreateDbContext(string[] args) => BuildReferralsDbContext("DemoDbContext", "sa", "SuperPassword1234!");
public static DemoDbContext BuildReferralsDbContext(string database, string username, string password, bool logging = false)
{
var connectionString = "Server=(localdb)\\mssqllocaldb;Database=DemoDbContext;Trusted_Connection=True;";
var optionsBuilder = new DbContextOptionsBuilder<DemoDbContext>();
_ = optionsBuilder.UseSqlServer(connectionString, x => x.MigrationsHistoryTable("MigrationsHistory", "mx"));
return new(optionsBuilder.Options);
}
}
Include provider and version information
EF Core version: 8.0.0-rc.1.23419.6
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 8.0
Operating system: Windows 11 Pro
IDE: Visual Studio 2022 Version 17.8.0 Preview 2.0
MaterializeJsonEntityCollection has type constraint so that i can use ICollection.Add method. We could/should use collection accessor AddStandalone instead
When running the .NET 8 console application below I run into the following exception (thrown at line 10). This exception is thrown when using " 8.0.0-rc.1.23419.6" but works as expected with "7.0.11"
If i change
to this
The code works as expected.
Demo Application:
Include provider and version information
EF Core version: 8.0.0-rc.1.23419.6 Database provider: Microsoft.EntityFrameworkCore.SqlServer Target framework: .NET 8.0 Operating system: Windows 11 Pro IDE: Visual Studio 2022 Version 17.8.0 Preview 2.0