You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Entity Framework Core调用DbSet.Add后Owned Type属性丢失值

EF Core Owned Type 相关问题

问题现象

使用Entity Framework Core开发项目时,遇到Owned Type相关异常:

  • 创建新的MainEntity并通过AddAsync添加到上下文后,ThirdEntity中的MyOwnedType属性会立即变为null,但SecondEntity中的该属性不受影响,且调用AddAsync前该属性有值。
  • 尝试先将ThirdEntity直接添加到DbSet时,它的MyOwnedType值不会丢失,但添加MainEntity到上下文后,ThirdEntity的MyOwnedType属性全部变为null。
  • 调用SaveChanges时抛出异常:

System.InvalidOperationException: 'Cannot save instance of 'MainEntity.MyOwnedTypeStart#MyOwnedType' because it is an owned entity without any reference to its owner. Owned entities can only be saved as part of an aggregate also including the owner entity.'

  • 添加日志后出现以下警告:

warn: 30/05/2024 11:52:30.440 CoreEventId.DuplicateDependentEntityTypeInstanceWarning[10001] (Microsoft.EntityFrameworkCore.Update)
The same entity is being tracked as different entity types 'ThirdEntity.MyOwnedType#MyOwnedType' and 'MainEntity.CompetenciaStart#MyOwnedType' with defining navigations. If a property value changes, it will result in two store changes, which might not be the desired outcome.

实体结构代码

class MainEntity
{
    public Guid Id { get; set; }
    public virtual List<SecondEntity>? Seconds { get; set; }
    public MyOwnedType MyOwnedTypeStart { get; set; } = null!;
    public MyOwnedType MyOwnedTypeEnd { get; set; } = null!;
}

class SecondEntity
{
    public Guid Id { get; set; }
    public Guid MainEntityId { get; set; }
    public virtual MainEntity? MainEntity { get; set; }
    public virtual List<ThirdEntity>? Third { get; set; }
    public MyOwnedType MyOwnedType { get; set; } = null!;
}

class ThirdEntity
{
    public Guid Id { get; set; }
    public Guid SecondEntityId { get; set; }
    public virtual SecondEntity? SecondEntity { get; set; }
    public MyOwnedType MyOwnedType { get; set; } = null!;
}

public record MyOwnedType 
{
    public EMonth Month { get; init; }
    public ushort Year { get; init; }
}

public enum EMonth
{
    January = 1,
    February = 2,
    March = 3,
    April = 4,
    May = 5,
    June = 6,
    July = 7,
    August = 8,
    September = 9,
    October = 10,
    November = 11,
    December = 12,
    ExtraMonth = 13
}

添加实体代码

public virtual Task AddAsync(MainEntity entity)
{
    // ... some code here ...

    return dbSet.AddAsync(entity).AsTask();
}

Owned Type配置代码

builder.OwnsOne(o => o.Competencia,
    sa =>
    {
        const string monthColumnName = "EMonth";
        const string yearColumnName = "Year";

        sa.Property(p => p.Month).HasColumnName(monthColumnName);
        sa.Property(p => p.Year).HasColumnName(yearColumnName);
    });

问题分析与解决思路

  1. 重复跟踪警告的核心原因:EF Core将同一个MyOwnedType实例同时跟踪为不同的拥有实体类型(如ThirdEntity.MyOwnedType和MainEntity.MyOwnedTypeStart)。因为EF Core要求每个Owned Type实例必须属于唯一的所有者,若在多个实体间复用同一个MyOwnedType实例,会触发跟踪冲突,最终导致属性被置空。
  2. 具体解决步骤:
    • 确保每个实体的MyOwnedType属性都是独立实例,不要在多个实体间复用同一个对象。比如创建ThirdEntity时,要新建new MyOwnedType { ... },而非引用其他实体的实例。
    • 检查Owned Type配置的完整性:当前配置仅针对Competencia属性(推测是MyOwnedTypeStart或MyOwnedTypeEnd的笔误),需确保MainEntity的MyOwnedTypeStart、MyOwnedTypeEnd,SecondEntity和ThirdEntity的MyOwnedType都通过OwnsOne完成正确配置。
    • 避免手动单独添加ThirdEntity到DbSet,而是通过MainEntity.Seconds[x].Third导航属性添加子实体,让EF Core自动维护所有者与Owned Type的关联关系。

内容的提问来源于stack exchange,提问作者Joao Paulo Salles Beraldo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 02:40:59