ASP.NET Core / EF Core 6:dbContext.saveChanges() 产生堆栈溢出错误

ASP.NET Core / EF Core 6: dbContext.saveChanges() produces stack overflow error

将数据保存到 dbContext.saveChanges()

时出现“堆栈溢出”错误
Stack overflow.
Repeat 87208 times:
--------------------------------
   at WebAPI.Models.WorkProfile..ctor()
   at WebAPI.Models.WorkAccount..ctor()
--------------------------------
   at DynamicClass..ctor()
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnTryRead(System.Text.Json.Utf8JsonReader ByRef, System.Type, System.Text.Json.JsonSerializerOptions, System.Text.Json.ReadStack ByRef, System.__Canon ByRef)
   at System.Text.Json.Serialization.JsonConverter`1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].TryRead(System.Text.Json.Utf8JsonReader ByRef, System.Type, System.Text.Json.JsonSerializerOptions, System.Text.Json.ReadStack ByRef, System.__Canon ByRef)
   at System.Text.Json.Serialization.JsonConverter`1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].ReadCore(System.Text.Json.Utf8JsonReader ByRef, System.Text.Json.JsonSerializerOptions, System.Text.Json.ReadStack ByRef)
   at System.Text.Json.Serialization.JsonConverter`1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].ReadCoreAsObject(System.Text.Json.Utf8JsonReader ByRef, System.Text.Json.JsonSerializerOptions, System.Text.Json.ReadStack ByRef)
etc. 
etc. 
etc..........

这是我的控制器:

[HttpPost]
[Consumes("application/json")]
public async Task<ActionResult<WorkAccount>> Post(WorkAccount workAccount)
{
    if (Request.HasJsonContentType())
    {
        // this runs: logs out JSONcontent.
        Console.WriteLine("JSON content");
    }
    else
    {
        Console.WriteLine("NO json!");
    }

    _context.WorkAccounts.Add(workAccount);
    await _context.SaveChangesAsync();

    return CreatedAtAction("GetTodoItem", workAccount);
}

这些是我的模型 类:

public class WorkAccount : BaseDateEntity
{
    public int WorkAccountId { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
    public WorkProfile? WorkProfile { get; set; } = new WorkProfile();
}

public class WorkProfile : BaseDateEntity
{
    public int WorkProfileId { get; set; }
    public int WorkAccountId { get; set; }
    public List<Booking> Bookings { get; set; } = new List<Booking>();
    public List<Advert> Adverts { get; set; } = new List<Advert>();
    public List<WorkProfileLanguage> WorkProfileLanguages { get; set; } = new List<WorkProfileLanguage>();
    public WorkAccount WorkAccount { get; set; } = new WorkAccount();
}

// and some more models...

FluentAPI 配置

public class WorkAccountConfig : IEntityTypeConfiguration<WorkAccount>
{
    public void Configure(EntityTypeBuilder<WorkAccount> modelBuilder)
    {
        modelBuilder
        .HasOne(x => x.WorkProfile)
        .WithOne(y => y.WorkAccount)
        .HasForeignKey<WorkProfile>(z => z.WorkAccountId);
    }
}

在这个错误之前,我有另一个错误。我的 WorkProfile 导航 属性 看起来像:public WorkProfile? WorkProfile { get; set; } 没有 = new WorkProfile() 初始化并且产生了以下错误:

System.NullReferenceException: Object reference not set to an instance of an object.

我也试过只返回 JSON 数据,它没有产生任何错误并且有效 json.

public async Task<ActionResult<WorkAccount>> Post(WorkAccount workAccount)
{
    return workAccount;
}

chrome 开发者工具的 console.log 输出。

{
    "workAccountId": 0,
    "email": "mail here",
    "password": "boo",
    "workProfile": null,
    "createdAt": "0001-01-01T00:00:00",
    "updatedAt": "0001-01-01T00:00:00"
}

我卡住了。有谁知道哪里出了问题?

任何时候 WorkAccountWorkProfile 被实例化,你都会创建一个无限循环,因为 WorkAccount 创建一个新的默认值 WorkProfile,它创建一个新的默认值 WorkAccount 创建一个新的 WorkProfile

我建议删除那些默认实例。

您只需尝试实例化其中之一即可获得相同的行为。

    using System;

    public class Program
    {
        public static void Main()
        {
            var w = new WorkAccount();
        }

        public class WorkAccount 
        {
            public int WorkAccountId { get; set; }
            public string Email { get; set; }
            public string Password { get; set; }
            public WorkProfile? WorkProfile { get; set; } = new WorkProfile();
        }

        public class WorkProfile 
        {
            public int WorkProfileId { get; set; }
            public int WorkAccountId { get; set; }
            public WorkAccount WorkAccount { get; set; } = new WorkAccount();
        }

    }

以上将导致

Stack overflow.
Repeat 130975 times:
--------------------------------
   at Program+WorkProfile..ctor()
   at Program+WorkAccount..ctor()
--------------------------------
   at Program.Main()
Command terminated by signal 6

删除默认实例运行没有问题。

    using System;

    public class Program
    {
        public static void Main()
        {
            var w = new WorkAccount();
        }

        public class WorkAccount 
        {
            public int WorkAccountId { get; set; }
            public string Email { get; set; }
            public string Password { get; set; }
            public WorkProfile? WorkProfile { get; set; }
        }

        public class WorkProfile 
        {
            public int WorkProfileId { get; set; }
            public int WorkAccountId { get; set; }
            public WorkAccount WorkAccount { get; set; }
        }

    }