Persistence as dumb IOChange tracking, and a gotcha you'd trust
No narration yet
Module 7 · Lesson 211 min

Change tracking, and a gotcha you'd trust

When you DO update an existing entity (rather than append), Fusion prefers EF's change tracking over hand-rolled bulk updates. The repository loads a tracked entity, the aggregate mutates its state, and SaveChangesAsync writes the diff. The anti-pattern is reaching for ExecuteUpdateAsync with a .Where(...) clause that re-encodes a domain predicate, because then the same rule lives in two places: the aggregate and the SQL WHERE.

Now a gotcha that's worth the whole lesson, because it's the kind of thing you'd read and trust. The FlightNote DBO has audit columns (CreatedBy, CreatedDateTimeUtc) filled by Postgres defaults (current_user, now()) on INSERT. It's tempting to read CreatedBy as "the operator who wrote the note." It is not.

This is the deeper habit the course is really teaching: read the code AND its comments for what's actually guaranteed, not what a name implies. A column called CreatedBy implies user attribution; the comment and the convention tell you it's the DB account. The reviewers who wrote these anti-patterns learned them the same way, one surprising PR at a time.

Practice

Try it yourself

Recall

Change tracking over ExecuteUpdate

Convention D3, stated.

When updating an existing entity, why does Fusion prefer loading a tracked entity and calling SaveChangesAsync over an ExecuteUpdateAsync with a .Where(...) predicate?

Quiz

What CreatedBy actually holds

The note DBO's CreatedBy is populated by a Postgres current_user default. Who does it identify?