Observing DbSet<>
Entity Framework Core observation support allows you to monitor changes to your entities in real-time using reactive extensions. This feature enables you to create observable queries that automatically update when data changes, either through your application or external database modifications.
Configuration
Section titled “Configuration”To enable observation support, you only need to register the observation services in your service collection.
Register Observation Services
Section titled “Register Observation Services”Add observation services to your service collection:
services.AddEntityFrameworkCoreObservation();This registers the necessary services for tracking entity changes and database-level notifications.
If your DbContext inherits from BaseDbContext and is registered using the Arc extension methods (AddDbContextWithConnectionString or AddReadOnlyDbContext), observation support is automatically enabled when the services are registered. No additional configuration is needed.
Manual Configuration (Advanced)
Section titled “Manual Configuration (Advanced)”If you’re not using BaseDbContext or the Arc registration methods, you can manually add observation support at registration time:
services.AddPooledDbContextFactory<MyDbContext>((serviceProvider, options) =>{ options.UseSqlServer(connectionString) .AddObservation(serviceProvider);});
services.AddScoped(serviceProvider =>{ var factory = serviceProvider.GetRequiredService<IDbContextFactory<MyDbContext>>(); return factory.CreateDbContext();});Important: When using pooled DbContext factories (
AddPooledDbContextFactory), all configuration must be done at registration time. You cannot modify options inOnConfiguringwhen pooling is enabled.
Once configured, you can create observable queries using extension methods on DbSet<TEntity>.
Observe a Collection
Section titled “Observe a Collection”Monitor changes to a collection of entities:
var observable = dbContext.MyEntities.Observe();observable.Subscribe(entities =>{ // Handle updated collection Console.WriteLine($"Collection updated: {entities.Count()} items");});Observe with Filter
Section titled “Observe with Filter”Apply filters to observe specific entities:
var observable = dbContext.Orders.Observe(order => order.Status == OrderStatus.Pending);observable.Subscribe(pendingOrders =>{ // Handle updates to pending orders only});Observe a Single Entity
Section titled “Observe a Single Entity”Monitor changes to a specific entity:
var observable = dbContext.Products.ObserveSingle(p => p.Sku == "ABC123");observable.Subscribe(product =>{ // Handle updates to the specific product});Observe by Id
Section titled “Observe by Id”Monitor a single entity using its identifier:
var observable = dbContext.Customers.ObserveById<Customer, Guid>(customerId);observable.Subscribe(customer =>{ // Handle updates to the customer});How It Works
Section titled “How It Works”The observation feature combines two notification mechanisms:
- In-Process Changes: Changes made through your application’s
DbContextare tracked via EF Core interceptors - Database-Level Changes: External changes are detected using database-specific notification mechanisms:
- SQL Server: Uses
SqlDependencyor polling - PostgreSQL: Uses
LISTEN/NOTIFY - SQLite: Uses polling
- SQL Server: Uses
When any change is detected, the observable query is re-executed and subscribers are notified with the updated results.
Change Detection
Section titled “Change Detection”The observation system detects changes when:
- Entities are added, modified, or deleted through
SaveChanges()orSaveChangesAsync() - External processes modify the database (via database-level notifications)
- Changes match the filter criteria of your observable query
Best Practices
Section titled “Best Practices”- Use filters to limit the scope of observations and improve performance
- Dispose of subscriptions when no longer needed to prevent memory leaks
- Consider using
ObserveSingleorObserveByIdwhen monitoring individual entities - Be mindful of database notification limits and capabilities for your specific database provider
Example: Real-Time Dashboard
Section titled “Example: Real-Time Dashboard”public class OrderDashboard{ private readonly IDisposable _subscription;
public OrderDashboard(MyDbContext dbContext) { _subscription = dbContext.Orders .Observe(o => o.Status == OrderStatus.Processing) .Subscribe(processingOrders => { UpdateDashboard(processingOrders); }); }
public void Dispose() { _subscription?.Dispose(); }
private void UpdateDashboard(IEnumerable<Order> orders) { // Update UI or metrics }}