What is a value object, and how is it different from an entity?
Quick Answer
An entity has an identity that persists through changes — a Customer is the same customer even if their name changes. A value object has no identity; it's defined entirely by its values and two with the same values are interchangeable — Money(10, "USD"), Address, DateRange. Value objects should be immutable.
An entity is something with an identity you track over time — a customer stays the same customer through every change to their details. A value object is the opposite: it has no id, it's just its values, and two value objects with the same contents are completely interchangeable — money, an address, a date range. Value objects are immutable and they're a great place to put rules, like a Money type that refuses to add two different currencies, or an EmailAddress that validates on construction. In C# a record gives you the value equality you want, and in EF Core you map them as owned types.
- Value objects encapsulate rules: a
Moneytype can enforce that you don't add USD to GBP; anEmailAddressvalidates format on construction. - C#
recordgives you value equality for free — a natural fit. - In EF Core, map them as owned types.
- Using value objects instead of primitives (“primitive obsession”) makes the model self-validating and expressive.