I am having so much fun with .NET 9 and EF Core 9. EF Core has very good support for Domain Driven Design. We can use owned entities to model value objects, and they are mapped in the database sensibly. EF Core has good default rules, but we can configure them to the teeth.
Collection of value objects are mapped to separate tables and they are always eager loaded with the aggregate. This causes potential performance issues. For read-only queries, we can use AsNonTracking to improve performance, and for commands we can use AsSplitQuery.
However, these operators are not without downsides. I ended up using regular entities for collections of value objects and making them inaccessible from the DBContext to force the use of aggregates. Those entity models can implement ValueObject behaviors, Id being one of the properties for equality.
I am happy with the middle ground achieved above where I can apply DDD and enjoy the best performance, with a bit of a hack.
Moving on, I also implemented audit trails to record all transactions for the capability of being able to roll back transactions. Then I found that the single owned entity in the domain is being treated as a separate entity by EF Core, therefore they use one entry in the audit log.
I do not like the look of the audit log with an implementation detail like owned entities jamming up the audit trail. So with regret, I unpacked them all and use regular properties instead for cleaner audit trails.
Takeaway: EF Core 9 supports value objects in many ways. However, I ended up not using any of them:
Eager loading of collections of value objects causes performance issue
the non-collection value objects are treated as stealth entities, polluting audit trails.
Top comments (0)