MSOACC
MSOACC

Reputation: 3675

Using EFCore to represent and store Value Objects without using Owned Types

My Entity currently has a property that should be a Value Object, but I don't know how to implement it. I am using .NET6 with EFCore and am using Entity mapping / configuration (i.e. code first).

Value Objects should not have IDs, but it will need a primary key to be stored in the database and I don't think that primary key should be the Value Object's value. Let me explain:

public class Race {
    public Guid Id { get; set; } 
    public Athlete AthleteA { get; set; }
    public Athlete AthleteB { get; set; }

    public RaceType RaceType { get; set; } // should be a value object
}

public class RaceType {
    public Guid Id { get; set; } // this ID probably shouldn't be there
    public string Name { get; set; }
}

RaceType may be something like "sprint" or "marathon", for example.

In .NET's documentation, it recommends making the Value Object a record instead of a class and making it an "owned type". However, there is a problem with this that I see. From their docs, the limitations of an "owned type" are:

My understanding is that I will have no ability to add new races directly, i.e. if I want to display a list of RaceTypes on an admin page and let the admin add new values to it. This can only be done by adding a new Race with that new RaceType. Is this correct?

What I want to do:

I feel what I need is the ability to remove the RaceType.Id property from the domain model and add it to the entity configuration so that EFCore knows how to store it (i.e. in dbo.RaceType and a foreign key in dbo.Race.FK_RaceType) without the domain model having any idea that it has an ID. However, I can see no way to do this.

Is it possible to achieve this? Is there a better way to represent Value Objects in EFCore such that they get their own DB table that can be modified directly rather than having to go through an owner?

Upvotes: 1

Views: 850

Answers (1)

Krishna Moniz
Krishna Moniz

Reputation: 508

You're question is for .NET 6, so I don't know how helpful this is.

In .NET 8 / EF Core 8 you can use complex type to handle value objects. See: https://devblogs.microsoft.com/dotnet/announcing-ef8-rc1/

This will not create a separate dbSet:

Complex type objects:
...
Must be defined as part of an entity type. (In other words, you cannot have a DbSet of a complex type.)
...

Value objects do not need a separate db set.

So, yeah. The EF Core 8 guideline is to use Complex types.

Upvotes: 1

Related Questions