簡體   English   中英

System.Text.Json.JsonException 'object cycle error' 被 DbSet.FindAsync 方法間接觸發

[英]System.Text.Json.JsonException 'object cycle error' gets indirectly triggered by DbSet.FindAsync method

我有以下 web API 操作方法:

[HttpGet]
[Route("/api/projects/{projectId:int}/tickets")]
public async Task<IActionResult> GetProjectTickets(int projectId)
{
  if (await _dbContext.Projects.FindAsync(projectId) is null)
  {
    return NotFound();
  }

  var tickets = await _dbContext.Tickets
    .Where(t => t.ProjectId == projectId)
    .ToListAsync();

  return Ok(tickets);
}

當我點擊此端點時,我收到以下錯誤消息:

System.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles.

但是,如果我從操作方法中刪除初始if塊,我會得到預期的 JSON 結果,如下所示:

[HttpGet]
[Route("/api/projects/{projectId:int}/tickets")]
public async Task<IActionResult> GetProjectTickets(int projectId)
{
  var tickets = await _dbContext.Tickets
    .Where(t => t.ProjectId == projectId)
    .ToListAsync();

  return Ok(tickets);
}

以下是相關的實體和 DbContext 類:

public class Project
{
  public int ProjectId { get; set; }

  [Required]
  [StringLength(50)]
  public string Name { get; set; }

  public List<Ticket> Tickets { get; set; }
}

public class Ticket
{
  public int? TicketId { get; set; }

  [Required]
  public int? ProjectId { get; set; }

  [Required]
  [StringLength(100)]
  public string Title { get; set; }

  public string Description { get; set; }

  [StringLength(50)]
  public string Owner { get; set; }

  public DateTime? ReportDate { get; set; }

  public DateTime? DueDate { get; set; }

  public Project Project { get; set; }
}

public class BugsDbContext : DbContext
{
  public BugsDbContext(DbContextOptions options) : base(options)
  {
    // Empty block.
  }

  public DbSet<Project> Projects { get; set; }

  public DbSet<Ticket> Tickets { get; set; }

  protected override void OnModelCreating(ModelBuilder modelBuilder)
  {
    modelBuilder.Entity<Project>()
      .HasMany(p => p.Tickets)
      .WithOne(t => t.Project)
      .HasForeignKey(t => t.ProjectId);
}

我的假設是,可能會觸發異常,因為 EF Core 以某種方式開始跟蹤FindAsync請求的實體,即使代碼中的任何變量/字段/屬性都沒有引用該實體。 雖然,我找不到任何證據來支持這個假設。 我可以在有關 EF Core 跟蹤行為的文檔中找到的最佳信息指出:

在跟蹤查詢中返回結果時,EF Core 將檢查實體是否已在上下文中。 如果 EF Core 找到現有實體,則返回相同的實例。

這是否意味着,在 web API 操作方法中,我使用FindAsync方法查詢的Project實體存儲在上下文中(即使沒有對其的引用); 並且當后續查詢返回所有票證時,與該Project實體對應的Ticket證實體會以隱式方式通過上下文填充其Project屬性,這實際上會導致 object 循環錯誤? 或者還有其他我完全想念的東西嗎?

最后一點,我知道這個問題可以通過在 action 方法的 if 塊中執行初始查詢來解決,如下所示:

if (await _bugsDbContext.Projects
  .AsNoTracking()
  .FirstOrDefaultAsync(p => p.ProjectId == projectId) is null)
{
  return NotFound();
}

但是,我的問題與解決此錯誤無關 我想知道是什么導致 object 循環錯誤,當FindAsync使用而沒有對查詢實體的任何引用時

這是我的第一個問題。 我事先已閱讀所有指南,但如果我遺漏了任何內容,請提前道歉。 謝謝!

我有以下 web API 操作方法:

[HttpGet]
[Route("/api/projects/{projectId:int}/tickets")]
public async Task<IActionResult> GetProjectTickets(int projectId)
{
  if (await _dbContext.Projects.FindAsync(projectId) is null)
  {
    return NotFound();
  }

  var tickets = await _dbContext.Tickets
    .Where(t => t.ProjectId == projectId)
    .ToListAsync();

  return Ok(tickets);
}

當我點擊此端點時,我收到以下錯誤消息:

System.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles.

但是,如果我從操作方法中刪除初始if塊,我會得到預期的 JSON 結果,如下所示:

[HttpGet]
[Route("/api/projects/{projectId:int}/tickets")]
public async Task<IActionResult> GetProjectTickets(int projectId)
{
  var tickets = await _dbContext.Tickets
    .Where(t => t.ProjectId == projectId)
    .ToListAsync();

  return Ok(tickets);
}

以下是相關的實體和 DbContext 類:

public class Project
{
  public int ProjectId { get; set; }

  [Required]
  [StringLength(50)]
  public string Name { get; set; }

  public List<Ticket> Tickets { get; set; }
}

public class Ticket
{
  public int? TicketId { get; set; }

  [Required]
  public int? ProjectId { get; set; }

  [Required]
  [StringLength(100)]
  public string Title { get; set; }

  public string Description { get; set; }

  [StringLength(50)]
  public string Owner { get; set; }

  public DateTime? ReportDate { get; set; }

  public DateTime? DueDate { get; set; }

  public Project Project { get; set; }
}

public class BugsDbContext : DbContext
{
  public BugsDbContext(DbContextOptions options) : base(options)
  {
    // Empty block.
  }

  public DbSet<Project> Projects { get; set; }

  public DbSet<Ticket> Tickets { get; set; }

  protected override void OnModelCreating(ModelBuilder modelBuilder)
  {
    modelBuilder.Entity<Project>()
      .HasMany(p => p.Tickets)
      .WithOne(t => t.Project)
      .HasForeignKey(t => t.ProjectId);
}

我的假設是,可能會觸發異常,因為 EF Core 以某種方式開始跟蹤FindAsync請求的實體,即使代碼中的任何變量/字段/屬性都沒有引用該實體。 雖然,我找不到任何證據來支持這個假設。 我可以在有關 EF Core 跟蹤行為的文檔中找到的最佳信息指出:

在跟蹤查詢中返回結果時,EF Core 將檢查實體是否已在上下文中。 如果 EF Core 找到現有實體,則返回相同的實例。

這是否意味着,在 web API 操作方法中,我使用FindAsync方法查詢的Project實體存儲在上下文中(即使沒有對其的引用); 並且當后續查詢返回所有票證時,與該Project實體對應的Ticket證實體會以隱式方式通過上下文填充其Project屬性,這實際上會導致 object 循環錯誤? 或者還有其他我完全想念的東西嗎?

最后一點,我知道這個問題可以通過在 action 方法的 if 塊中執行初始查詢來解決,如下所示:

if (await _bugsDbContext.Projects
  .AsNoTracking()
  .FirstOrDefaultAsync(p => p.ProjectId == projectId) is null)
{
  return NotFound();
}

但是,我的問題與解決此錯誤無關 我想知道是什么導致 object 循環錯誤,當FindAsync使用而沒有對查詢實體的任何引用時

這是我的第一個問題。 我事先已閱讀所有指南,但如果我遺漏了任何內容,請提前道歉。 謝謝!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM