EF Core 2.0 (re)introduces the concept of Complex types which are called Owned types in EF Core. I find the new naming confusing but hey that’s me…
Anyway let’s have a look at how we can use these Complex Owned types. We’ll start by creating a Supplier class with an Address;
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Address | |
{ | |
public string Street{get;set;} | |
public string Number{get;set;} | |
public string City{get;set;} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Supplier | |
{ | |
public Guid Id{get;set;} | |
public string Name{get;set;} | |
public Address Address{get;set;} | |
} |
Important to notice is that the Address does not have it’s own Id but is embedded into the Supplier class.
To configure the Owned types mapping, you have to use the OwnedOne method in the mapping file. If you want to further configure the properties of the Owned type, you’ll have to repeat the statement for every property in the Owned type:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class SupplierMap : IEntityTypeConfiguration<Supplier> | |
{ | |
public void Configure(EntityTypeBuilder<Supplier> builder) | |
{ | |
builder.HasKey(x => x.Id); | |
builder.Property(x => x.Id) | |
.HasValueGenerator<GuidValueGenerator>() | |
.ValueGeneratedOnAdd() | |
.IsRequired(); | |
builder.Property(x => x.Name); | |
builder.OwnsOne(x => x.Address) | |
.Property(y => y.Street) | |
.IsRequired(); | |
builder.OwnsOne(x => x.Address) | |
.Property(y => y.Number) | |
.IsRequired(); | |
builder.OwnsOne(x => x.Address) | |
.Property(y => y.City) | |
.IsRequired(); | |
} | |
} |
That's it!