How far should an entity take care of its properties values by itself?
- by Kharlos Dominguez
Let's consider the following example of a class, which is an entity that I'm using through Entity Framework.
- InvoiceHeader
- BilledAmount (property, decimal)
- PaidAmount (property, decimal)
- Balance (property, decimal)
I'm trying to find the best approach to keep Balance updated, based on the values of the two other properties (BilledAmount and PaidAmount).
I'm torn between two practices here:
Updating the balance amount every time BilledAmount and PaidAmount are updated (through their setters)
Having a UpdateBalance() method that the callers would run on the object when appropriate.
I am aware that I can just calculate the Balance in its getter.
However, it isn't really possible because this is an entity field that needs to be saved back to the database, where it has an actual column, and where the calculated amount should be persisted to.
My other worry about the automatically updating approach is that the calculated values might be a little bit different from what was originally saved to the database, due to rounding values (an older version of the software, was using floats, but now decimals).
So, loading, let's say 2000 entities from the database could change their status and make the ORM believe that they have changed and be persisted back to the database the next time the SaveChanges() method is called on the context.
It would trigger a mass of updates that I am not really interested in, or could cause problems, if the calculation methods changed (the entities fetched would lose their old values to be replaced by freshly recalculated ones, simply by being loaded).
Then, let's take the example even further.
Each invoice has some related invoice details, which also have BilledAmount, PaidAmount and Balance (I'm simplifying my actual business case for the sake of the example, so let's assume the customer can pay each item of the invoice separately rather than as a whole).
If we consider the entity should take care of itself, any change of the child details should cause the Invoice totals to change as well.
In a fully automated approach, a simple implementation would be looping through each detail of the invoice to recalculate the header totals, every time one the property changes.
It probably would be fine for just a record, but if a lot of entities were fetched at once, it could create a significant overhead, as it would perform this process every time a new invoice detail record is fetched.
Possibly worse, if the details are not already loaded, it could cause the ORM to lazy-load them, just to recalculate the balances.
So far, I went with the Update() method-way, mainly for the reasons I explained above, but I wonder if it was right.
I'm noticing I have to keep calling these methods quite often and at different places in my code and it is potential source of bugs.
It also has a detrimental effect on data-binding because when the properties of the detail or header changes, the other properties are left out of date and the method has no way to be called.
What is the recommended approach in this case?