簡體   English   中英

Ef core 6 嘗試使用時拋出錯誤 500.ThenInclude 方法

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

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