[c#] .NET Core 3.0 Entity Framework에서 그룹 조인을 수행하는 방법은 무엇입니까?

.NET Core 3.0의 변경 사항으로 인해

… NavigationExpandingExpressionVisitor ‘가 실패했습니다. 이는 EF Core의 버그 또는 제한 사항을 나타낼 수 있습니다. 자세한 내용은 https://go.microsoft.com/fwlink/?linkid=2101433 을 참조
하십시오 .) —> System.InvalidOperationException : LINQ 식 ‘GroupJoin, …

이것은 매우 간단한 쿼리이므로 .NET CORE 3.0에서 수행 할 수있는 방법이 있어야합니다.

 var queryResults1 = await patients
            .GroupJoin(
                _context.Studies,
                p => p.Id,
                s => s.Patient.Id,
                (p, studies) => new 
                {
                    p.DateOfBirth,
                    p.Id,
                    p.Name,
                    p.Sex,
                   Studies =studies.Select(s1=>s1)
                }
            )
            .AsNoTracking().ToListAsync();

나는 기본적으로 Linq 쿼리 (또는 위와 같은 방법 구문)를 찾고 환자에 대한 연구를 연결하고 연구를 빈 목록으로 설정하거나 주어진 환자에 대한 연구가없는 경우 null을 설정합니다.

어떤 아이디어? 이것은 .NET Core 2.2에서 작동했습니다. 또한 위의 MSFT 링크는 주요 변경 사항이 클라이언트 측 평가와 관련이 있으며 생성 된 쿼리가 전체 테이블을 읽은 다음 클라이언트 측에 조인하거나 필터링해야하는 것을 피합니다. 그러나이 간단한 쿼리를 사용하면 조인을 쉽게 서버 측에서 수행 할 수 있습니다.



답변

여기 에서 설명했듯이 데이터베이스에서 지원하지 않는 쿼리를 시도하고 있습니다. EF Core 2는 클라이언트 측 평가를 사용하여 코드를 작동 시켰지만 EF Core 3는 데이터 세트가 증가함에 따라 디버그하기 어려운 성능 문제가 발생하기 때문에 클라이언트 측 편의가 제공되므로 거부합니다.

을 사용 DefaultIfEmpty하여 환자의 연구에 참여한 다음와 수동으로 그룹화 할 수 있습니다 ToLookup.

var query =
    from p in db.Patients
    join s in db.Studies on p.Id equals s.PatientId into studies
    from s in studies.DefaultIfEmpty()
    select new { Patient = p, Study = s };

var grouping = query.ToLookup(e => e.Patient); // Grouping done client side

위의 예는 전체 환자 및 연구 엔터티를 가져 오지만 대신 열을 체리 픽으로 선택할 수 있습니다. 환자에게 필요한 데이터가 각 스터디에 대해 반복하기에 너무 큰 경우, 조인 된 쿼리에서 환자 ID 만 선택하고 나머지 환자 데이터는 별도의 비조 인 쿼리로 쿼리합니다.


답변

정확히 같은 문제와 큰 어려움을 겪었습니다. .net Core 3.0은 메소드 구문 (아직?)에서 Join 또는 Groupjoin을 지원하지 않습니다. 재미있는 부분은 쿼리 구문에서 작동합니다.

이것을 시도하십시오. 조금 구문 구문이있는 쿼리 구문입니다. 이것은 왼쪽 외부 조인이 좋은 올바른 SQL 쿼리로 훌륭하게 변환되며 데이터베이스에서 처리됩니다. 나는 당신의 모델을 얻지 못했기 때문에 구문을 확인해야합니다 ….

var queryResults1 = 
    (from p in _context.patients
    from s in _context.Studies.Where(st => st.PatientId == p.Id).DefaultIfEmpty()
    select new
    {
        p.DateOfBirth,
        p.Id,
        p.Name,
        p.Sex,
        Studies = studies.Select(s1 => s1)
    }).ToListAsync();


답변