How to use Specifications with a DbContext
Specifications can be applied to any DbSet<>
or IQueryable<>
source using the WithSpecification
extension method. This extension method is defined in the Ardalis.Specification.EntityFrameworkCore
and Ardalis.Specification.EntityFramework6
plugin packages.
Let’s assume we have the following setup.
public class CustomerSpec : Specification<Customer>
{
public CustomerSpec(int age)
{
Query.Where(x => x.Age > age)
.Include(x => x.Addresses)
.OrderBy(x => x.FirstName);
}
}
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
public class SampleDbContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
public SampleDbContext(DbContextOptions<SampleDbContext> options)
: base(options)
{
}
}
Apply the specification to a given DbSet
as follows.
var spec = new CustomerSpec(20);
var customer = await dbContext.Customers
.WithSpecification(spec)
.ToListAsync();
The WithSpecification
extension methods returns the IQueryable<>
source, and you may continue building the state. Having said that, you may chain multiple specifications as follows.
var spec1 = new CustomerByAgeSpec(20);
var spec2 = new CustomerByLastNameSpec("Smith");
var customer = await dbContext.Customers
.WithSpecification(spec1)
.WithSpecification(spec2)
.ToListAsync();