How to deal with value objects in Entity Framework?

前端 未结 3 1183
灰色年华
灰色年华 2020-12-30 01:49

How do I persist value objects in Entity Framework without polluting my domain model? EF (well, relational DBs in general) require me to define a key - which my value object

3条回答
  •  臣服心动
    2020-12-30 02:15

    I think it may be useful to know for those who use Entity Framework Core 2.0 that

    Having no ID field in a class to be used by Entity Framework (EF) was not possible until EF Core 2.0, which greatly helps to implement better value objects with no ID.

    Here is detailed information from Microsoft about this feature:

    Persist value objects as owned entity types in EF Core 2.0 and later Even with some gaps between the canonical value object pattern in DDD and the owned entity type in EF Core, it's currently the best way to persist value objects with EF Core 2.0 and later.

    The owned entity type feature was added to EF Core since version 2.0.

    An owned entity type allows you to map types that do not have their own identity explicitly defined in the domain model and are used as properties, such as a value object, within any of your entities. An owned entity type shares the same CLR type with another entity type (that is, it's just a regular class). The entity containing the defining navigation is the owner entity. When querying the owner, the owned types are included by default.

    Just by looking at the domain model, an owned type looks like it doesn't have any identity. However, under the covers, owned types do have identity, but the owner navigation property is part of this identity.

    The identity of instances of owned types is not completely their own. It consists of three components:

    -The identity of the owner

    -The navigation property pointing to them

    -In the case of collections of owned types, an independent component (supported in EF Core 2.2 and later).

    By convention, a shadow primary key is created for the owned type and it will be mapped to the same table as the owner by using table splitting. This allows to use owned types similarly to how complex types are used in EF6 in the traditional .NET Framework.

    It is important to note that owned types are never discovered by convention in EF Core, so you have to declare them explicitly.

    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).

    Owned entities limitations

    -You can't create a DbSet of an owned type (by design).

    -You can't call ModelBuilder.Entity() on owned types (currently by design).

    -No support for optional (that is, nullable) owned types that are mapped with the owner in the same table (that is, using table splitting). This is because mapping is done for each property, we don't have a separate sentinel for the null complex value as a whole.

    -No inheritance-mapping support for owned types, but you should be able to map two leaf types of the same inheritance hierarchies as different owned types. EF Core will not reason about the fact that they are part of the same hierarchy.

    Main differences with EF6's complex types

    -Table splitting is optional, that is, they can optionally be mapped to a separate table and still be owned types.

    -They can reference other entities (that is, they can act as the dependent side on relationships to other non-owned types).

    https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ffffd-cqrs-patterns/implement-value-objects

提交回复
热议问题