dotnet / dotnet/efcore

EF Core Inheritance: Profile Field Null on Retrieval Despite of Configured Relationships

Open
#32,352 15 comments 7 reactions 0 assignees View on GitHub
area-dbcontext customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

I'm encountering an issue with Entity Framework Core (EF Core) related to lazy loading, inheritance, and property retrieval. Initially, I had the following entity classes:

```csharp
public class Pool
{
public int Id { get; set; }
public Profile? Profile
{
get
{
return ORMAProfileAccessor as Profile ?? ORMBProfileAccessor;
}

set
{
switch (value)
{
case AProfile aProfile:
ORMAProfileAccessor = aProfile;
break;
case BProfile bProfile:
ORMBProfileAccessor = bProfile;
break;
default:
throw new InvalidCastException("Invalid profile type");
}
}
}
internal virtual AProfile? ORMAProfileAccessor { get; set; }
internal virtual BProfile? ORMBProfileAccessor { get; set; }
}

public abstract class Profile
{
public Profile() { }
public int Id { get; set; }
}

public class AProfile : Profile
{
public AProfile() { }
public virtual Pool? Pool { get; set; }
}

public class BProfile : Profile
{
public BProfile() { }
public virtual Pool? Pool { get; set; }
}
```
In the OnModelCreating method, I configured the relationships as follows:

```csharp
modelBuilder.Entity().HasOne(P => P.Pool).WithOne(Q => Q.ORMAProfileAccessor).HasForeignKey("AProfileId").IsRequired(false);
modelBuilder.Entity().HasOne(P => P.Pool).WithOne(Q => Q.ORMBProfileAccessor).HasForeignKey("BProfileId").IsRequired(false);
modelBuilder.Entity().Ignore(P => P.Profile);
```
The issue I'm facing now is that after saving a Pool object to the database with associated Profile, upon retrieving the Pool elsewhere in the code, the Profile field remains null. However, retrieving a Profile separately shows that the Pool field within the Profile object is correctly populated. For example:

```csharp
var retrievedPool = dbContext.Pools.FirstOrDefault();
if (retrievedPool != null)
{
Console.WriteLine($"Retrieved Pool ID: {retrievedPool.Id}");
Console.WriteLine($"Retrieved Pool Profile ID: {retrievedPool.Profile?.Id}"); // This returns null
}
```
How can I ensure that when retrieving a Pool, the Profile field is populated with the associated Profile type?

Any insights or suggestions would be highly appreciated. Thank you!

EF Core version: 6.0.16
Database provider:Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 6.0
IDE: Visual Studio 2022 17.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.