[英]Ef core 6 throws error 500 when trying to use .ThenInclude method
我有兩個表 Employee 和 Skill,它們使用與 EmployeeSkill 關聯 class 的多對多關系連接。 但是,下面的查詢可以正常工作:1] 當我調用 employees 方法時,我得到了正確數量的 Counted Skill 引用對象,但它們都被初始化為零,2] 當我嘗試添加 ThenInclude 查詢時,它會拋出 500 錯誤。
非常感謝您的寶貴時間
編輯:一種解決方案是向 Startup.cs 添加以下代碼行:
services.AddControllers().AddJsonOptions(x => x.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles);
服務器異常:
執行請求時發生未處理的異常。 System.Text.Json.JsonException:檢測到可能的 object 循環。 這可能是由於循環或 object 深度大於最大允許深度 32
客戶端異常:
Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: Response status code does not indicate success: 500 (Internal Server Error).
System.Net.Http.HttpRequestException: Response status code does not indicate success: 500 (Internal Server Error).
at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
at System.Net.Http.HttpClient.GetStreamAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
at SkillMatrix.Client.Services.EmployeeDataService.GetEmployeesAsync() in C:\Users\Onelity-mefraimidis\Downloads\Onelity related\.NET projects\SkillMatrix\SkillMatrix.Client\Services\EmployeeDataService.cs:line 30
at SkillMatrix.Client.Features.EmployeeView.EmployeeOverviewPage.OnInitializedAsync() in C:\Users\Onelity-mefraimidis\Downloads\Onelity related\.NET projects\SkillMatrix\SkillMatrix.Client\Features\EmployeeView\EmployeeOverviewPage.cs:line 54
at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
上下文(在 sql 數據庫中正確添加):
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Configure a Many-to-Many Relationship using Fluent API
modelBuilder.Entity<Employee>()
.HasMany(e => e.Skills)
.WithMany(s => s.Employees)
.UsingEntity<EmployeeSkill>(
j => j.HasOne(m => m.Skill).WithMany(g => g.EmployeeSkills),
j => j.HasOne(m => m.Employee).WithMany(g => g.EmployeeSkills),
je =>
{
je.HasKey("EmployeesId", "SkillsId");
je.HasData(
new EmployeeSkill { EmployeesId = 1, SkillsId = 1 },
new EmployeeSkill { EmployeesId = 1, SkillsId = 3 },
new EmployeeSkill { EmployeesId = 1, SkillsId = 4 },
new EmployeeSkill { EmployeesId = 1, SkillsId = 5 },
new EmployeeSkill { EmployeesId = 1, SkillsId = 8 },
new EmployeeSkill { EmployeesId = 2, SkillsId = 1 },
new EmployeeSkill { EmployeesId = 2, SkillsId = 2 },
new EmployeeSkill { EmployeesId = 2, SkillsId = 3 },
new EmployeeSkill { EmployeesId = 2, SkillsId = 11 },
new EmployeeSkill { EmployeesId = 2, SkillsId = 15 },
new EmployeeSkill { EmployeesId = 3, SkillsId = 10 },
new EmployeeSkill { EmployeesId = 3, SkillsId = 22 },
new EmployeeSkill { EmployeesId = 3, SkillsId = 23 },
new EmployeeSkill { EmployeesId = 3, SkillsId = 40 },
new EmployeeSkill { EmployeesId = 3, SkillsId = 47 }
);
}
);
課程:
public class EmployeeSkill
{
public int SkillsId;
public int EmployeesId;
public Employee Employee;
public Skill Skill;
}
public class Employee
{
public int Id { get; set; }
[Required]
[StringLength(50, ErrorMessage = "First name is too long.")]
public string FirstName { get; set; }
[Required]
[StringLength(50, ErrorMessage = "Last name is too long.")]
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[Phone]
public string PhoneNumber { get; set; }
public bool Smoker { get; set; }
public MaritalStatus MaritalStatus { get; set; }
public Gender Gender { get; set; }
[StringLength(1000, ErrorMessage = "Comment length cannot exceed 1000 characters.")]
public string Comment { get; set; }
public DateTime? JoinedDate { get; set; }
public DateTime? LastUpdateDate { get; set; }
public DateTime? ExitDate { get; set; }
public int JobCategoryId { get; set; }
public JobCategory JobCategory { get; set; }
#region Navigation Properties
public virtual EmployeeAddress Address { get; set; }
public virtual ICollection<Skill> Skills { get; set; }
public virtual ICollection<EmployeeSkill> EmployeeSkills { get; set; }
#endregion
}
public class Skill
{
public int Id { get; set; }
[Required]
[StringLength(50, ErrorMessage = "Name is too long.")]
public string Name { get; set; }
public string Description { get; set; }
public Level Level { get; set; }
public int SkillCategoryId { get; set; }
#region Navigation Properties
public virtual SkillCategory SkillCategory { get; set; }
public virtual ICollection<Employee> Employees { get; set; }
public virtual ICollection<EmployeeSkill> EmployeeSkills { get; set; }
#endregion
}
服務方式:
public async Task<IEnumerable<EmployeeSkillResponse>> GetEmployeeSkillsAsync()
{
return await JsonSerializer.DeserializeAsync<IEnumerable<EmployeeSkillResponse>>(await _httpClient.GetStreamAsync("api/employeeskills"),
new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
}
存儲庫:
public IEnumerable<Employee> GetEmployees()
{
var query1 = _skillMatrixContext.Employees.Include(employee => employee.EmployeeSkills).ToList();
// initially was query
//var query = _skillMatrixContext.Employees;
// this throws 500 error
//var query2 = _skillMatrixContext.Employees.Include(employee => employee.EmployeeSkills).ThenInclude(skill=>skill.Skill).ToList();
return query1;
}
Controller 方法:
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable<EmployeeResponse>))]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[Produces(MediaTypeNames.Application.Json)]
public ActionResult<IEnumerable<EmployeeResponse>> GetEmployees()
{
var employeesFromRepo = _employeeRepository.GetEmployees();
return Ok(_mapper.Map<IEnumerable<EmployeeResponse>>(employeesFromRepo));
}
一種解決方案是向 Startup.cs 添加以下代碼行:
services.AddControllers().AddJsonOptions(x => x.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles);
還必須注意 AsNoTracking() 可以在查詢結束時使用。 引用 Svyatoslav Danyliv: EF Core fixup navigation properties via ChangeTracker,它可能會導致加載對象中的循環引用——這就是你有異常的原因。 AsNoTracking() 禁用此修復和更改跟蹤,這可能會加速加載記錄。 通常在寫API的時候,它使用DTO類通過網絡返回信息,這樣的問題幾乎不會出現
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.