Skip to content

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

@karczk-dnv

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

Metadata

Metadata

Assignees

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions