219
CHAPTER 6 | Tackle Business Complexity in a Microservice with DDD and CQRS Patterns
modelBuilder.
ApplyConfiguration
(
new
OrderEntityTypeConfiguration
());
modelBuilder.
ApplyConfiguration
(
new
OrderItemEntityTypeConfiguration
());
//...Additional type configurations
}
In
the following code, the persistence infrastructure is defined for the Order entity:
// Part of the OrderEntityTypeConfiguration.cs class
//
public
void
Configure
(EntityTypeBuilder
orderConfiguration)
{
orderConfiguration.
ToTable
(
"orders"
, OrderingContext.
DEFAULT_SCHEMA
);
orderConfiguration.
HasKey
(o => o.
Id
);
orderConfiguration.
Ignore
(b => b.
DomainEvents
);
orderConfiguration.
Property
(o => o.
Id
)
.
ForSqlServerUseSequenceHiLo
(
"orderseq"
, OrderingContext.
DEFAULT_SCHEMA
);
//Address value object persisted as owned entity in EF Core 2.0
orderConfiguration.
OwnsOne
(o => o.
Address
);
orderConfiguration.
Property
(
"OrderDate"
).
IsRequired
();
//...Additional validations, constraints and code...
//...
}
In the previous code, the
orderConfiguration.OwnsOne(o => o.Address)
method specifies that the
Address
property is an owned entity of the
Order
type.
By default, EF Core conventions name the database columns for the properties of the owned entity
type as
EntityProperty_OwnedEntityProperty
. Therefore, the internal properties of
Address
will
appear in the
Orders
table with the names
Address_Street
,
Address_City
(and so on for
State
,
Country
, and
ZipCode
).
You can append the
Property().HasColumnName()
fluent method to rename those columns. In the
case where
Address
is a public property, the mappings would be like the following:
orderConfiguration.
OwnsOne
(p => p.
Address
)
.
Property
(p=>p.
Street
).
HasColumnName
(
"ShippingStreet"
);
orderConfiguration.
OwnsOne
(p => p.
Address
)
.
Property
(p=>p.
City
).
HasColumnName
(
"ShippingCity"
);
It’s possible to chain the
OwnsOne
method in a fluent mapping. In the following hypothetical example,
OrderDetails
owns
BillingAddress
and
ShippingAddress
, which are both
Address
types. Then
OrderDetails
is owned by the
Order
type.
orderConfiguration.
OwnsOne
(p => p.
OrderDetails
, cb =>
{
cb.
OwnsOne
(c => c.
BillingAddress
);
cb.
OwnsOne
(c => c.
ShippingAddress
);
});
//...
//...
public
class
Order
{
public
int
Id {
get
;
set
; }
public
OrderDetails OrderDetails {
get
;
set
; }
220
CHAPTER 6 | Tackle Business Complexity in a Microservice with DDD and CQRS Patterns
}
public
class
OrderDetails
{
public
Address BillingAddress {
get
;
set
; }
public
Address ShippingAddress {
get
;
set
; }
}
public
class
Address
{
public
string
Street {
get
;
set
; }
public
string
City {
get
;
set
; }
}
Additional details on owned entity types
•
Owned types are defined when you configure a navigation property to a particular type using
the OwnsOne fluent API.
•
The definition of an owned type in our metadata model is a composite of: the owner type, the
navigation property, and the CLR type of the owned type.
•
The identity (key) of an owned type instance in our stack is a composite of the identity of the
owner type and the definition of the owned type.
Owned entities capabilities
•
Owned types can
reference other entities, either owned (nested owned types) or non-owned
(regular reference navigation properties to other entities).
•
You can map the same CLR type as different owned types in the same owner entity through
separate navigation properties.
•
Table splitting is set up by convention, but you can opt out by mapping the owned type to a
different table using ToTable.
•
Eager loading is performed automatically on owned types,
that is, there’s
no need to call
.Include()
on the query.
•
Can be configured with attribute
[Owned]
, using EF Core 2.1 and later.
•
Can handle collections of owned types (using version 2.2 and later).
Dostları ilə paylaş: