[英]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.