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

EF Core迁移时触发NullReferenceException问题求助

解决EF Core OwnsMany嵌套OwnsOne导致的NullReferenceException

问题原因

这个空引用异常是EF Core处理**嵌套Owned Entity(OwnsMany内部嵌套OwnsOne)**时,隐式外键生成逻辑冲突引发的。当在OwnsMany配置块中嵌套OwnsOne时,EF Core无法正确识别父、子Owned Entity的关联关系,进而触发空引用错误。

修复方案

1. 显式配置Owned Entity间的关联外键

在嵌套的OwnsOne配置中,明确指定与父Owned Entity的外键关联,帮助EF Core正确识别依赖关系:

ftb.OwnsOne(ft => ft.BoardingPass, bp =>
{
    bp.ToTable("PassengerBoardingPasses");
    
    bp.Property(b => b.Id)
        .ValueGeneratedNever()
        .HasConversion(
            b => b.Value,
            value => BoardingPassId.Create(value));

    bp.Property(b => b.Gate)
        .HasMaxLength(8);
    
    bp.Property(b => b.BoardingTime)
        .IsRequired();
    
    // 显式配置与父PassengerFlightTickets的外键关联
    bp.WithOwner().HasForeignKey("FlightTicketId");
});

2. 调整导航属性访问模式的设置方式

将导航属性的访问模式设置与OwnsMany配置链式调用,避免在导航属性未完全初始化时访问:

builder.OwnsMany(
    p => p.FlightTicketIds,
    ftb =>
    {
        // ... 原有OwnsMany内部配置
    })
// 链式设置访问模式
.Metadata.SetPropertyAccessMode(PropertyAccessMode.Field);

3. 升级EF Core到稳定版本

若使用的是EF Core 5.x及更早版本,这类嵌套Owned Entity的bug已在后续版本中修复,建议升级到6.0或7.0的稳定版本后再尝试生成迁移。

4. 检查Owned Entity定义

确保FlightTicketIds对应的实体类(如PassengerFlightTicket)定义正确,所有属性有合适的访问修饰符,且无与EF Core映射逻辑冲突的自定义构造函数或属性逻辑。

修改后的完整配置代码

namespace Ceyehat.Infrastructure.Persistence.Configurations;

public class PassengerConfigurations : IEntityTypeConfiguration<Passenger>
{
    public void Configure(EntityTypeBuilder<Passenger> builder)
    {
        ConfigurePassengersTable(builder);
        ConfigurePassengerFlightTicketsTable(builder);
    }

    private void ConfigurePassengerFlightTicketsTable(EntityTypeBuilder<Passenger> builder)
    {
        builder.OwnsMany(
            p => p.FlightTicketIds,
            ftb =>
            {
                ftb.ToTable("PassengerFlightTickets");
                
                ftb.HasKey(ft => ft.Id);
                
                ftb.Property(ft => ft.Id)
                    .ValueGeneratedNever()
                    .HasConversion(
                        ft => ft.Value,
                        value => FlightTicketId.Create(value));
                
                ftb.Property(ft => ft.FlightId)
                    .ValueGeneratedNever()
                    .HasConversion(
                        ft => ft.Value,
                        value => FlightId.Create(value));

                ftb.Property(ft => ft.SeatId)
                    .ValueGeneratedNever()
                    .HasConversion(
                        ft => ft.Value,
                        value => SeatId.Create(value));

                ftb.OwnsOne(ft => ft.BoardingPass, bp =>
                {
                    bp.ToTable("PassengerBoardingPasses");
                    
                    bp.Property(b => b.Id)
                        .ValueGeneratedNever()
                        .HasConversion(
                            b => b.Value,
                            value => BoardingPassId.Create(value));

                    bp.Property(b => b.Gate)
                        .HasMaxLength(8);
                    
                    bp.Property(b => b.BoardingTime)
                        .IsRequired();
                    
                    // 显式配置外键关联
                    bp.WithOwner().HasForeignKey("FlightTicketId");
                });
            })
        .Metadata.SetPropertyAccessMode(PropertyAccessMode.Field);
    }

    private void ConfigurePassengersTable(EntityTypeBuilder<Passenger> builder)
    {
        builder.ToTable("Passengers");
        
        builder.HasKey(p => p.Id);
        
        builder.Property(p => p.Id)
            .ValueGeneratedNever()
            .HasConversion(
                p => p.Value,
                value => PassengerId.Create(value));
        
        builder.Property(p => p.CustomerId)
            .ValueGeneratedNever()
            .HasConversion(
                p => p.Value,
                value => CustomerId.Create(value));
    }
}

内容的提问来源于stack exchange,提问作者ad3m VALORANT

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 21:46:07