복붙노트

[SQL] EF 핵심 엔티티 테이블 구조를 참조 카테고리 부모 ID 자체지도

SQL

EF 핵심 엔티티 테이블 구조를 참조 카테고리 부모 ID 자체지도

데이터베이스 테이블 :

영상

나는 EF 코어에 범주 테이블을 매핑하는 데이 방법을 시도했다 :

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Category>(entity =>
    {
        entity
            .HasMany(e => e.Children)
            .WithOne(e => e.Parent) 
            .HasForeignKey(e => e.ParentId);
    });
}

실재:

[Table("Category"]
public class Category : EntityBase
{
    [DataType(DataType.Text), MaxLength(50)]
    public string Name { get; set; }

    public int? ParentId { get; set; }

    public int? Order { get; set; }

    [ForeignKey("ParentId")]
    public virtual Category Parent { get; set; }

    public virtual ICollection<Category> Children { get; set; }
}

그런 다음 저장소에 :

public override IEnumerable<Category> GetAll()
{ 
    IEnumerable<Category> categories = Table.Where(x => x.Parent == null).Include(x => x.Children).ThenInclude(x=> x.Children);
    return categories;
}

이 일을 아무것도하지만 후 3 개 수준에 상관없이 () 또는 ThenInclude () 포함 호출 횟수 반환되지 않았습니다.

나는 재귀 함수와 하위 범주를 채우는 코드 나 자신 쓰기 결국 :

public override IEnumerable<Category> GetAll()
{
    IEnumerable<Category> categories = Table.Where(x => x.Parent == null).ToList();
    categories = Traverse(categories);
    return categories;
}

private IEnumerable<Category> Traverse(IEnumerable<Category> categories)
{
    foreach(var category in categories)
    {
        var subCategories = Table.Where(x => x.ParentId == category.Id).ToList();
        category.Children = subCategories;
        category.Children = Traverse(category.Children).ToList();
    }
    return categories;
}

사람이 테이블 계층 구조를 얻을 내가 예에서 제공 한 종류의 개체에 매핑 할 저장 프로 시저를 작성하는 더 좋은 방법을 알고 있나요?

해결법

  1. ==============================

    1.EF (그리고 일반적으로 LINQ는)으로 인해 순환 식 / CTE 지원의 부족으로 데이터 같은 문제 로딩 나무가 있습니다.

    EF (그리고 일반적으로 LINQ는)으로 인해 순환 식 / CTE 지원의 부족으로 데이터 같은 문제 로딩 나무가 있습니다.

    당신이 (필터링 나뭇 가지 반대) 전체 트리를로드 할 경우에 대비하지만, 간단한 기반 솔루션을 포함 있습니다. 당신이 필요로 하나가 포함하고 EF 탐색 속성 픽스 업 당신을 위해 일을 할 것입니다. 당신이 당신의 샘플로는 루트 노드를 얻을 필요가 때, 트릭 쿼리가 된 후 (평소와 같이 AsEnumerable ()를 사용하여) 개체 컨텍스트에 LINQ로 전환하여 실현 (및 탐색 속성이 고정 된) 필터를 적용하는 것입니다 .

    다음은 단일 SQL 쿼리로 원하는 결과를 생성한다 그래서 :

    public override IEnumerable<Category> GetAll()
    { 
        return Table
           .Include(x => x.Children)
           .AsEnumerable()
           .Where(x => x.Parent == null)
           .ToList();
    }
    
  2. from https://stackoverflow.com/questions/46160780/map-category-parent-id-self-referencing-table-structure-to-ef-core-entity by cc-by-sa and MIT license