In EFCore, when do I need to add [Owned] attribute to a value object?

报错内容:System.InvalidOperationException:“The entity type 'xxx' cannot be configured as owned because it has already been configured as a non-owned. If you want to override previous configuration first remove the entity type from the model by calling 'Ignore'.

Cause: I added a value object to the entity. The value objects are as follows:

There is an enumeration type attribute Weekday, which is not configured explicitly due to the [Owned] feature, resulting in an error 

    public class WeeklyLoopTimeStamp:ValueObject
    {
        // 日期
        public DayOfWeek Weekday
        {
            get; set;
        }
        // 时间
        public DateTime TimePoint
        {
            get; set;
        }

        protected override IEnumerable<object> GetAtomicValues()
        {
            yield return Weekday;
            yield return TimePoint;
        }
    }

 

In EF Core, when you want to mark a property as a value object and want EF Core to configure it asComplex Type, you need to add the [Owned] attribute to the attribute of the value object.

The benefit of adding the [Owned] attribute is that EF Core will automatically handle the mapping and relationship between the attribute and the entity it belongs to. It simplifies the code and reduces the effort of manual configuration.

However, adding the [Owned] attribute is not necessary in all cases. Here are some descriptions of the situation:

1. When the data type of an attribute itself is a simple value type (such as string, int, DateTime, etc.), EF Core will automatically treat it as part of the composite type without adding the [Owned] attribute.

2. When the data type of the attribute is a custom class or structure, and you want to treat it as an independent entity type (with its own unique identifier) ​​rather than a composite type, you do not need to add the [Owned] attribute .

3. When the property is a collection type (such as List, ICollection, etc.), EF Core will automatically configure it as a navigation property, and there is no need to add the [Owned] attribute.

So, you need to add the [Owned] attribute on the value object's properties only if you really want the property to be configured as a value object and stored as a composite type in the same database table.

If you do not add the [Owned] attribute without reporting an error, it is likely because EF Core's default behavior correctly infers that the property should be treated as a composite type. However, to make your intentions clear and improve code clarity, it is recommended to explicitly add the [Owned] attribute to the value object's properties.

Expansion questions:

1. In what structure are value objects stored in the data table?

In the database, if an entity has a value object attribute, the attribute of the value object is usually used as a column in the entity table for storage.

Simply understand: the attributes of the value object will be extracted into the entity attributes, thus becoming a separate column

For the WxTemplateForPlanOrderEntity entity you mentioned, if WeeklyLoopTimeStamp is a value object property, then a column containing the WeeklyLoopTimeStamp property is usually created based on the design of the database.

Specifically, you can serialize the value of the WeeklyLoopTimeStamp attribute into an appropriate data type (such as string, JSON, etc.) based on the database type you are using and the requirements of the ORM framework, and store it in the corresponding column of the database table.

For example, in a relational database, you can serialize the value of the WeeklyLoopTimeStamp property in JSON format and store it as a varchar or json type column. In a NoSQL database, you may choose to store the value of the WeeklyLoopTimeStamp attribute directly as a document or field.

It should be noted that the mapping relationship needs to be configured between the columns in the database and the attributes of the entity. This is usually handled by the ORM framework, which defines the mapping relationship between entity properties and database columns through specific annotations, configuration files, or code.

To sum up, the storage method in the database depends on the database type, ORM framework and related configuration, but generally speaking, value object properties will be stored as separate columns in the entity table.

2. What if the value object under the entity is a one-to-many relationship? How will it be stored in the data table?

example:

    /// <summary>
    /// 发送数据时机 按周循环
    /// </summary>
    public List<WeeklyLoopTimeStamp> WeeklyLoopTimeStamp
    {
        get;
        set;
    }

Then it needs to be configured according to the ORM, and usually another association table will be created. Foreign keys are associated with entities.

builder.OwnsMany( );

The specific configuration method passed in needs to be formulated according to the project specifications.

Guess you like

Origin blog.csdn.net/dongnihao/article/details/134652273