Q & A

시삽: 레드플러스 님 
게시판 이동:
 제목 : Re : Asp.net core blazor 문의
글번호: 1015
작성자: 레드플러스
작성일: 2022/01/20 오후 8:05:00
조회수: 1958

 

안녕하세요.

 

(1)

EF Core의 조인 결과를 담을 수 있는 또 다른 모델/뷰모델 클래스를 추가로 만드는 작업은 일상적으로 보면 좋습니다.

(2)

새로운 클래스 보다는 하나의 클래스에  관련된 하위 또는 상위 클래스에 대한 정보를 담을 수 있는 Navigation Property를 만들고,

이곳에 Include 메서드로 조인 결과를 담고 사용하는 방법도 좋은 방법입니다.

 

저는 이 방법 중 Navigation Property를 사용하는 방법을 좋아합니다. 

 

(3) 

저는 강의에서 조인이 필요한 경우에는

모델 클래스에 자식 테이블 또는 부모 테이블에 해당하는 네비게이션 속성을 두고

리포지토리 클래스에서는 LINQ의 Include 메서드를 사용하는 편입니다.

 

예들 들어, 모델 클래스에서 Navigation Property를 사용하여 Join의 결과를 담을 수 있는 그릇 속성을 만들 수 있습니다. 

public class Incident
{
    public int Id { get; set; }

    [Display(Name = "Property")]
    public Property Properties { get; set; } // 네비게이션 속성 추가... 
    [Display(Name = "Property")]
    public int? PropertyId { get; set; }

    public ReportType ReportTypes { get; set; }
    [Display(Name = "Incident Type")]
    public int? ReportTypeId { get; set; }

    public ReportSpecific ReportSpecific { get; set; }
    [Display(Name = "Report Specific")]
    public int? ReportSpecificId { get; set; }

    public CaseStatus CaseStatuses { get; set; }
    [Display(Name = "Incident Status")]
    [ForeignKey("CaseStatuses")]
    public int? CaseStatusId { get; set; }

    ...

 

제 강의 소스 중 Include 메서드를 많이 사용한 리포지토리 클래스의 일부입니다. 

public async Task<ArticleSet<Incident, int>> GetArticlesWithDateAsync<TParentIdentifier>(
    int pageIndex,
    int pageSize,
    string searchField,
    string searchQuery,
    string sortOrder,
    TParentIdentifier parentIdentifier,
    DateTime from,
    DateTime to)
{
    var items = 
        _context.Incidents
            .Include(d => d.Locations)
            .Include(d => d.Properties) // Include 메서드로 Join
            .Include(d => d.Sublocations)
            .Include(x => x.CaseStatuses)
            .Include(x => x.ReportTypes)
            .Include(x => x.ReportSpecific)
            .Include(x => x.Departments)
            .AsQueryable();

    if (from != null && to != null)
    {
        items = items.Where(it => (it.CreatedDate == null) || it.CreatedDate >= from && it.CreatedDate <= to)
    }

    if (!string.IsNullOrEmpty(searchQuery))
    {
        items = items.Where(
            m => m.CaseNumber.Contains(searchQuery) 
            || 
            m.DailyLogNumber.Contains(searchQuery) 
            || 
            m.Properties.Name.Contains(searchQuery) 
            || 
            m.CreatedBy.Contains(searchQuery) 
            || 
            m.ModifiedBy.Contains(searchQuery) 
            || 
            m.Details.Contains(searchQuery) 
            || 
            m.Summary.Contains(searchQuery) 
            || 
            m.Reference.Contains(searchQuery) 
            || 
            m.Locations.Name.Contains(searchQuery) 
            || 
            m.Sublocations.SublocationName.Contains(searchQuery) 
            ||
            m.Resolution.Contains(searchQuery)
        );
    }

    var totalCount = await items.CountAsync();

    switch (sortOrder)
    {
        case "Status":
            items = items.OrderBy(m => m.CaseStatuses.CaseStatusName).ThenByDescending(m => m.Id);
            break;
        case "StatusDesc":
            items = items.OrderByDescending(m => m.CaseStatuses.CaseStatusName).ThenByDescending(m => m.Id);
            break;
        case "Number":
            items = items.OrderBy(m => m.CaseNumber).ThenByDescending(m => m.Id);
            break;
        case "NumberDesc":
            items = items.OrderByDescending(m => m.CaseNumber).ThenByDescending(m => m.Id);
            break;
        case "Specific":
            items = items.OrderBy(m => m.ReportSpecific.Specific).ThenByDescending(m => m.Id);
            break;
        case "SpecificDesc":
            items = items.OrderByDescending(m => m.ReportSpecific.Specific).ThenByDescending(m => m.Id);
            break;
        case "Property":
            items = items.OrderBy(m => m.Properties.Name).ThenByDescending(m => m.Id);
            break;
        case "PropertyDesc":
            items = items.OrderByDescending(m => m.Properties.Name).ThenByDescending(m => m.Id);
            break;
        case "Type":
            items = items.OrderBy(m => m.ReportTypes.TypeName).ThenByDescending(m => m.Id);
            break;
        case "TypeDesc":
            items = items.OrderByDescending(m => m.ReportTypes.TypeName).ThenByDescending(m => m.Id);
            break;
        case "Creator":
            items = items.OrderBy(m => m.CreatedBy).ThenByDescending(m => m.Id);
            break;
        case "CreatorDesc":
            items = items.OrderByDescending(m => m.CreatedBy).ThenByDescending(m => m.Id);
            break;
        case "Created":
            items = items.OrderBy(m => m.CreatedDate).ThenByDescending(m => m.Id);
            break;
        case "CreatedDesc":
            items = items.OrderByDescending(m => m.CreatedDate).ThenByDescending(m => m.Id);
            break;
        default:
            items = items.OrderByDescending(m => m.Id);
            break;
    }

    items = items.Skip(pageIndex * pageSize).Take(pageSize);

    return new ArticleSet<Incident, int>(await items.AsNoTracking().ToListAsync(), totalCount);
}

 

(4) 

Blazor Server의 EF Core 부분은 MVC, Razor, Blazor 영역 모두 공통입니다.

Microsoft Docs의 다음 자습서도 참고해보면 좋습니다. 

 

ASP.NET Core MVC 및 EF Core - 자습서 시리즈

https://docs.microsoft.com/ko-kr/aspnet/core/data/ef-mvc/?view=aspnetcore-6.0

https://docs.microsoft.com/ko-kr/aspnet/core/data/ef-rp/intro?view=aspnetcore-6.0&tabs=visual-studio

 

 

결론적으로 말씀드려,

 

한번 페이지 로드시

부모 테이블의 1번 데이터 읽어올 때 해당 1번 데이터 관련된 모든 자식 테이블 정보를 함께 읽어와서 사용할 때에는

부모 클래스에 Navigation 속성 추가 후 리포지토리에서 Include 메서드로 자식 테이블 지정하여 바로 즉시 로딩하여 사용하는 방법을 권해드립니다.

 

이 내용 관련해서는 앞에서 제시한 Microsoft Docs의 EF Core 자습서를 참고해 보세요.

 

 

감사합니다.

 

 

 

 


On 2022-01-20 오후 7:15:00, '김상윤' wrote:

 

 


데브렉에서 학습중인데 어디에다 물어볼지 몰라 여기에 남깁니다.

강의는 잘듣고 있습니다. 언제나 감사드립니다.

 

질문은

Blazor에서 efcore6으로 프로젝트를 진행중입니다.

보통 테이블 별로 Repository를 만들어서 관리하는데

A테이블과 B테이블을 조인해서 A, B테이블 정보를 함께 UI바인딩을 해야하는 경우는 어떻게 해야 할까요

조인을 하게되면 익명타입으로 반환되는데 이 익명타입이 매개변수로 전달을 못하는 타입이라서 dynamic으로 해봤지만 바인딩할 때 해당 값을 꺼낼 수 없는거 같더라구요

조인을 할 때마다 모델을 새롭게 만들어줘야 하는건 너무 코딩양이 많아질거 같고 좋은 방버있으면 답변 부탁드립니다.!

 
이전 글   다음 글 삭제 수정 답변 글쓰기 리스트

(댓글을 남기려면 로그인이 필요합니다.)

관련 아티클 리스트
  제       목 파일 작성자 작성일 조회
이전글 안녕하세요! - C#만세 2022-01-28 1956
  Asp.net core blazor 문의 - 김상윤 2022-01-20 2022
현재글 Re : Asp.net core blazor 문의 - 레드플러스 2022-01-20 1958
다음글 c# 기초강좌 - 김현기 2022-01-18 2023
 
손님 사용자 Anonymous (손님)
로그인 Home