I have the following DbContext using a TPC mapping strategy to add basic fields to all entities and in the background a Postgresql database server and .NET 6.0.
public MyDbContext(DbContextOptions<MyDbContext> options) : base(options) { }// devices trackingpublic DbSet<Device> Devices { get; set; }public DbSet<DeviceLending> DevicesLendings { get; set; }protected override void OnModelCreating(ModelBuilder modelBuilder){ // Default values from db functions modelBuilder .Entity<DbBase>() .UseTpcMappingStrategy() .Property(e => e.Created) .HasDefaultValueSql("now()"); // Auto Includes modelBuilder .Entity<Device>() .Navigation(e => e.Lendings) .AutoInclude(); modelBuilder .Entity<DeviceLending>() .Navigation(e => e.Device) .AutoInclude();}The DbBase class looks like this:
public abstract class DbBase{ [Key] public int Id { get; set; } public Instant Created { get; set; } public Instant Updated { get; set; } [Timestamp] public uint Version { get; set; }}And the actual data classes like this:
public class Device : DbBase{ public ICollection<DeviceLending> Lendings { get; } = new List<DeviceLending>(); public string Comment { get; set; } = string.Empty;}public class DeviceLending : DbBase{ public string Comment { get; set; } = String.Empty; public int DeviceId { get; set; } public Device Device { get; set; } = null!;}Now when I try to load the devices including the Lendings property I get an exception
System.InvalidCastException: Unable to cast object of type 'devices.Entities.Device' to type 'devices.Entities.DeviceLending'
Why is EF Core trying to load the Device type as Lendings which are of the type DeviceLending? Is this related to the TPC mapping strategy?
I tried commenting out the AutoInclude, then it worked but I need the lendings to be included. Also is tried adding a setter to the lending property but this didn't change anything.
I have found other issues like this only but they dated back 5 years and were a bug on EF Core which is fixed in my version.
The full exception:
fail: Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost[111]
Unhandled exception in circuit '5xqWOiz4ASoSDGW8EUUVSgQvQ-XQTuwqp0axa7fVeFk'.
System.InvalidCastException: Unable to cast object of type 'devices.Entities.Device' to type 'devices.Entities.DeviceLending'.
at lambda_method90(Closure , QueryContext , DbDataReader , ResultContext , SingleQueryResultCoordinator )
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.g__ProcessCurrentElementRow|24_0[TIncludingEntity,TIncludedEntity](<>c__DisplayClass24_02& ) at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.PopulateIncludeCollection[TIncludingEntity,TIncludedEntity](Int32 collectionId, QueryContext queryContext, DbDataReader dbDataReader, SingleQueryResultCoordinator resultCoordinator, Func3 parentIdentifier, Func3 outerIdentifier, Func3 selfIdentifier, IReadOnlyList1 parentIdentifierValueComparers, IReadOnlyList1 outerIdentifierValueComparers, IReadOnlyList1 selfIdentifierValueComparers, Func5 innerShaper, INavigationBase inverseNavigation, Action2 fixup, Boolean trackingQuery) at lambda_method92(Closure , QueryContext , DbDataReader , ResultContext , SingleQueryResultCoordinator ) at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable1.AsyncEnumerator.MoveNextAsync()at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable1 source, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable1 source, CancellationToken cancellationToken)at devices.Services.DbService.GetDevicesAsync(CancellationToken ct) in [redacted]/Services/DbService.cs:line 68at devices.Shared.DeviceGrid.LoadDevices() in [redacted]/Shared/DeviceGrid.razor:line 40at devices.Shared.DeviceGrid.OnInitializedAsync() in [redacted]/Shared/DeviceGrid.razor:line 45at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)