Select and SelectMany

The Select and SelectMany features behave the same as their LINQ counterparts. They are used to project, transform, or flatten query results.

How to Use Select

The Select method is used to project elements into a new form. In the context of specifications, it’s commonly used to map entities to DTOs, or select specific properties.

To use Select, your specification should inherit from Specification<T, TResult>, where T is the entity type and TResult is the projection type. This enables strongly typed experience in the builder and during the evaluation.

public class CustomerSpec : Specification<Customer, CustomerDto>
{
    public CustomerSpec(int age)
    {
        Query.Where(x => x.Age > age)
             .Select(x => new CustomerDto(x.Id, x.Name));
    }
}

You can also project to a single property.

public class CustomerSpec : Specification<Customer, string?>
{
    public CustomerSpec()
    {
        Query.Select(x => x.Name);
    }
}

How to use SelectMany

The SelectMany method is used to flatten nested collections. It projects each element to an IEnumerable and flattens the results into a single sequence. In the following example, it will return a flat list of all Address objects across all Customer entities.

public class CustomerSpec : Specification<Customer, Address>
{
    public CustomerSpec()
    {
        Query.SelectMany(c => c.Addresses);
    }
}

Why Use Select and SelectMany?

  • Reduces data transfer by returning only needed fields
  • Supports projection to DTOs
  • Enables efficient queries. The projection is applied at the query level, so only the selected fields are retrieved from the data source.
  • SelectMany is ideal for flattening nested collections like child entities