Open Closed

Persisting Value Objects in database #1908


User avatar
0
vincent.goh created

I have read the "Implementing Domain Driven Design" ebook and have some questions on how to use and implement Value Objects in ABP according to DDD, particularly in persisting Value Objects in database.

On page 28 of the ebook where there's an example of IssueLabel as a Value Object, it seems to suggest that Value Objects should be used to implement associative entities / bridging tables to establish one-to-many or many-to-many relationships between entities.

However, I don't see the option of creating a Value Object using the CRUD Page Generator in ABP Suite and I don't see any examples or documentation of how Value Objects should be coded in ABP for persistence in a DBMS like SQL Server. As a result, I have been creating Entities for associative entities / bridging tables for my current ABP solutions.

Any advice on implementing Value Objects in ABP and storing it Value Objects in SQL databases will be helpful. Thanks.


7 Answer(s)
  • User Avatar
    0
    gterdem created
    Senior .NET Developer

    This question is not related with ABP but Value Object concept in Domain Driven Design. So you may get better responses if you ask it under domain driven design at stackoverflow.

    However I will try to explain.

    A value object:

    • Does not have an identity key: No Id field.
    • Does not exist on its own: Must be created with the entity it is owned by.
    • Is immutable: Should be created with valid value and shouldn't be changed in it's life cycle.
    • Has an identity which is a compound of other attributes instead of single key: The reason why methods like Equals, GetHashCode are overriden to check if value is unique. (Abp ValueObject class has GetAtomicValues method).

    Knowing these above, you can not create value objects using CRUD page generator since it can not exist on it is own. But we can talk about improvements in suit about value object generation on selected entity. However, value object is a concept of domain driven design and people may mismatch it with regular 1-1 relation or they may not use DDD at all.

    You need to understand the concept of value object better to decide what portions of your aggragate or entity can be represented as value object.

    To persist in database using EfCore, you can use fluent api as below:

    Entity<MyEntity>().OwnsOne(t=>t.MyValueObject)
    
    

    You can check Microsoft documentation about implementing value objects. I also suggest checking Julie Lerman talks about DDD and EfCore 3.

  • User Avatar
    0
    vincent.goh created

    Thanks for your explanation on the use of Value Objects in DDD. These are useful information.

    My question is more about whether Value Objects should be used for associative entities in a SQL database. On page 28 of Halil's ebook, he used Value Object for an associate entity called "IssueLabel". See diagram below.

    However, when I looked at ABP framework's own implementation of such associative entities like AbpUserRole or AbpUserOrganizationUnits, Entities are used instead of Value Objects.

    Just wanted to know if associative entities/tables that map relationships between entities should be using Entities or Value Objects in ABP framework as Halil seems to be suggesting something different from the actual implementation in his ebook.

    Thanks.

    Best regards, Vincent

  • User Avatar
    0
    hikalkan created
    Support Team Co-Founder

    Hi Vicent,

    My main motivation of designing IssueLabel as ValueObject is to show its usage. However, when it comes to choose between entities and value objects highly depends on your domain.

    For such relation tables, you can go with value objects or entities, actually doesn't matter much because they have no business. If you think a relation object can change later, then you should make it as entity (since value objects are immutable in ideal). For example, assume that we have a UserRole class with UserId and RoleId, then this can be value object or entity, doesn't matter much. However, if you add a IsActive property to UserRole classi, which is enabled/disabled to temporary disable a role for a user, then this should be entity, not a value object.

    Value objects are ideal to associate domain logic and business to simple values. As a common example, a Money value object can be useful instead of a decimal Amount property for an entity (if you define Money, then Amount's type becomes Money which explicitly shows that this is a money). Also, you can add some methods on the Money object to collect the money domain logic in a single place.

  • User Avatar
    0
    vincent.goh created

    Thanks Halil for your clarifications! It's most helpful.

    One feature I would like to request in the ABP Suite is to allow the creation of an Entity with composite keys rather than a primary key, as shown in the screenshot below.

    This will greatly assist in creating associative entities that use a composite key, like in the case of AbpUserRole where UserId and RoleId are used for its composite key.

  • User Avatar
    0
    hikalkan created
    Support Team Co-Founder

    Thanks for the suggestion. I've added it to the product backlog to consider later.

  • User Avatar
    0
    vincent.goh created

    By the way, I just realized that EF Core 5 removes the need to code associative entities for many-to-many relationships between Entities. This helps to separate the domain model from the data model.

    https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-5.0/whatsnew

  • User Avatar
    0
    alper created
    Support Team Director

    as the main question is answered, closing the issue. reopen anytime if you have problem with the main question.

Made with ❤️ on ABP v9.1.0-preview. Updated on November 11, 2024, 11:11