Skip to content

EF8 core: filtering by enum doesn't work with TPH and OfType #32865

Description

@karczk-dnv

Code

context.Technologies has TPH, discriminator is based on TechnologyType enum (8 different values)

public static class ContextExtensions
{
    public static IQueryable<TechnologyDto> StorageTechnologiesQuery(this AppDbContext context) =>
        context.Technologies
            .Include(x => x.Manufacturer)
            .Where(x => (x.TechnologyType == TechnologyType.StorageA
                    || x.TechnologyType == TechnologyType.StorageB
                    || x.TechnologyType == TechnologyType.StorageC
                    || x.TechnologyType == TechnologyType.StorageD));

    public static IQueryable<TechnologyDto> StorageTechnologyWithDetailsQuery(this AppDbContext context) =>
        StorageTechnologiesQuery(context)
            .Include(x => ((StorageATechnologyDto)x).SomeDetailsX)
            .Include(x => ((StorageATechnologyDto)x).SomeDetailsY)
            .Include(x => ((StorageATechnologyDto)x).SomeDetailsZ)
            .Include(x => ((StorageCTechnologyDto)x).SomeDetailsX)
            .Include(x => ((StorageCTechnologyDto)x).SomeDetailsY)
            .Include(x => ((StorageCTechnologyDto)x).SomeDetailsZ)
            .Include(x => ((StorageDTechnologyDto)x).SomeDetailsY)
                .ThenInclude(x => x.AssociatedData)
                    .ThenInclude(x => x.Manufacturer)
            .Include(x => ((StorageDTechnologyDto)x).SomeDetailsX)
            .Include(x => ((StorageDTechnologyDto)x).SomeDetailsZ)
            .Include(x => ((StorageDTechnologyDto)x).SomeDetailsX)
            .Include(x => ((StorageDTechnologyDto)x).SomeDetailsY);
}

Case:

var entity = await _context.StorageTechnologyWithDetailsQuery()
    .OfType<StorageDTechnologyDto>()
    .FirstOrDefaultAsync(x => x.Id == request.Id, cancellationToken);

Include verbose output

.NET 8 & EF core 8.0.1 produces WHERE 0 = 1

SELECT TOP(1) [t].[Id], [t].[CreatedAt], [t].[CreatedBy], [t].[Description], ...other columns
FROM [Technologies] AS [t]
INNER JOIN [Manufacturers] AS [m] ON [t].[ManufacturerId] = [m].[Id]
LEFT JOIN [StorageDTechnologySomeDetailsY] AS [t0] ON [t].[Id] = [t0].[TechnologyId]
LEFT JOIN [StorageDTechnologySomeDetailsX] AS [t1] ON [t].[Id] = [t1].[TechnologyId]
WHERE 0 = 1

It worked in .NET 7 & EF7

Workaround

Replace

.Where(x => (x.TechnologyType == TechnologyType.StorageA
    || x.TechnologyType == TechnologyType.StorageB
    || x.TechnologyType == TechnologyType.StorageC
    || x.TechnologyType == TechnologyType.StorageD));

by

.Where(x => (x is StorageATechnologyDto
    || x is StorageBTechnologyDto
    || x is StorageCTechnologyDto
    || x is StorageDTechnologyDto));

Include provider and version information

EF Core version: core 8.0.1
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 8.0
Operating system: Windows & Linux
IDE: Visual Studio 2022 17.8.4

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions