I have two databasecontexts FooContext, BarContext.
For FooContext, when certain entities in the dbSet changes, I need to project these entities to related entities in BarContext. I am looking at the best ways to implement such a job.
My current attempt involves inheriting an interface for the relevant entities, filtering these out in overridden FooContext.SaveChangesAsync() before calling a separate mapper (using dependencyInjection) to update the relevant tables in BarContext
// Baz.cs
public class Baz : IProjectedEntity {
// baz-definition
}
// FooContext.cs
public class FooContext : DbContext {
private IJobSpawner _jobSpawner;
public FooContext(IJobSpawner jobSpawner){
_jobSpawner=jobSpawner;
}
public DbSet<Baz> Baz {get;}
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = new()) {
ChangeTracker.DetectChanges();
var projections = ChangeTracker
.Entries<IProjectedEntity>()
.Where(e => e.State != EntityState.Unchanged)
.Select(e => e.Entity).ToList();
int changes = await base.SaveChangesAsync(cancellationToken);
await _jobSpawner.ProjectEntities(projections);
return changes;
}
}
Then the implementation of IJobSpawner takes dependency on BarContext and does the necessary mappings.
- Is this a bad idea?
- What is an alternative way of doing this?
I have also played a bith with the thought of defining an attribute for class properties, such that projections only happen if certain properties is changed
note : The method i have proposed does work, but I feel there should be a better, less cluttered way of achieving the same result. I don't like having to much internal logic in the context