dotnet / dotnet/efcore

Casting down in TPH should filter by the discriminator when accessing properties mapped to shared columns

Open
#29,913 5 comments 0 reactions 0 assignees View on GitHub
area-query breaking-change customer-reported
Dominant language
C#
Stars
14.8k
Forks
3.4k
PR merge metrics
PR metrics pending

Description

In TPH, it's possible to map properties from different siblings in the hierarchy to the same database column. In this scenario, when the base class is cast down in a query and a property is accessed, we'd missing a check on the discriminator, meaning that we'd erroneously return instances of the sibling as well.

C#:

```c#
_ = await ctx.Blogs.Where(b => ((SpecialBlog1)b).Foo == "something").ToListAsync();

public class BlogContext : DbContext
{
public DbSet Blogs { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlServer(@"Server=localhost;Database=test;User=SA;Password=Abcd5678;Connect Timeout=60;ConnectRetryCount=0;Encrypt=false")
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging();

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity();
modelBuilder.Entity();
}
}

public class Blog
{
public int Id { get; set; }
}

public class SpecialBlog1 : Blog
{
[Column("Shared")]
public required string Foo { get; set; }
}

public class SpecialBlog2 : Blog
{
[Column("Shared")]
public required string Bar { get; set; }
}
```

Resulting SQL:

```sql
SELECT [b].[Id], [b].[Discriminator], [b].[Shared]
FROM [Blogs] AS [b]
WHERE [b].[Shared] = N'something'
```

This also returns instances of SpecialBlog2. It seems like the WHERE clause should contain a condition for the discriminator.

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.