If your IQueryProvider supports casting projected instances to a base Type, you can project to derived Types via configured conditions. For example:

// Using an EF Core DbContext:
var animalDtos = await context
    .ProjectTo<AnimalDto>(cfg => cfg
        .If(a => a.Type == AnimalType.Dog)
        .If(a => a.Type == AnimalType.Cat)
        .If(a => a.Type == AnimalType.Gorilla)

A query projection will be generated which creates the appropriate derived Type for the AnimalType. If the Animal.Type does not match a configured value, an AnimalDto is created. If AnimalDto is abstract, the Animal is projected to null.