이 LINQ 쿼리에서 컴파일 타임 오류가 발생하는 이유는 무엇입니까?

StackOverflow https://stackoverflow.com/questions/20354027

  •  25-08-2022
  •  | 
  •  

문제

아래 코드를 컴파일 할 때 컴파일 시간 오류가 발생하고 이유를 알 수 없습니다.

관계는 많은 관계에 많은 관계가 있습니다

 var contacts = groups_to_querry
                .SelectMany(x => x.Contacts)
                .Where(x => x.ID == Guid.Empty)
                .SelectMany(p => p.ContactDetails)
                .Where(x => x.ID == Guid.Empty)
                .SelectMany(x => x.Contacts);  //This line gives me a compile time error 
                //Error : The Type argumetns for method 'System.Linq.Enumerable.SelectMany<TSource,Tresult>
                //(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,
                //System.Collections.Generic.IEnumerable<TResult>>)' cannot be infrred from the usage.  
                //Try specifying the type arguments explicitly
도움이 되었습니까?

해결책

두 번째로 당신이 요청합니다 .SelectMany(x => x.Contacts), 당신은 현재 컬렉션과 함께 일하고 있습니다 ContactDetails. 당신이 사용할 수 있다는 것은 의심 스럽다 SelectMany 그 위에. 사용해야합니다 Select 대신에.

SelectMany 여러 항목 컬렉션을 선택하여 하나로 넣으려면 사용됩니다. IEnumerable. Select 개별 분야에서 사용됩니다. 유형의 객체로 작업하고 있기 때문에 ContactDetail (내가 연락처가 하나만있을 수 있다고 생각하는 경우) 사용이 필요합니다. Select

편집 : 다음은 간단히 말해서 단계별로하고있는 일입니다.

groups_to_querry.SelectMany(x => x.Contacts): 쿼리하려는 모든 그룹에서 많은 연락처를 모두 선택합니다. 각 그룹에는 많은 연락처가 있으므로 모두 하나의 연락처에 있습니다. IEnumerable 유형 모음 Contact

.Where(x => x.ID == Guid.Empty): ...하지만 빈 ID와의 연락처 만

.SelectMany(p => p.ContactDetails): 그런 다음 해당 연락처의 모든 연락처 검사를 선택하십시오. 각 연락처에는 많은 연락처가 있습니다. IEnumerable 유형 모음 ContactDetail

.Where(x => x.ID == Guid.Empty): ...하지만 빈 ID가있는 연락처도 있습니다.

.SelectMany(x => x.Contacts);: 이제 각 contactDetails의 많은 연락처를 선택하십시오. 그러나 컴파일러는 연락처와 연락처간에 일대일 관계가 있음을 알고 있기 때문에 (다른 방법으로는 다른 방법이 아님) 그 진술은 불가능하므로 컴파일 오류가 표시됩니다.

다른 팁

의도 한 쿼리를 "여러 연락처 그룹에서 ID = Guid.Empty를 가진 모든 연락처를 선택하고 모두 id = guid.empty가있는 세부 사항이 있습니다"라고 해석합니다.

코드가 실제로 해석되는 방식은 "Guid.Empty가있는 모든 연락처에서 GUID.Empty가있는 모든 세부 사항을 선택하고 해당 세부 사항에서 모든 연락처를 선택하십시오"입니다. 첫 번째 문제는 세부 사항에서 선택하게된다는 것입니다. 이것은 결승을 의미합니다 SelectMany a Select, 왜냐하면 x.Contacts 다음은 세부 사항에서 연락처로의 다중 관계를 나타냅니다.

두 번째 문제는 각 세부 사항에 대해 동일한 접점이 포함되어 있기 때문에 결과에는 접점 중복이 포함된다는 것입니다. 대신해야 할 일은 다음과 같은 세부 사항 컬렉션을 기반으로 연락처를 직접 필터링하는 것입니다.

groups_to_query
.SelectMany(g => g.Contacts)
.Where(c => c.ID == Guid.Empty)
.Where(c => c.ContactDetails.All(d => d.ID == Guid.Empty))

이것은 또한 세부 사항이없는 연락처를 선택하여 쿼리와 다른 동작이므로 원하는지 확실하지 않습니다. 다른 필터를 추가 할 수 있습니다 ContactDetails.Any() 그렇지 않다면.

편집하다: 엔티티 프레임 워크를 사용하고 있기 때문에 위의 내용은 작동하지 않을 것입니다. 하위 쿼리에서 세부 사항을 선택한 다음 실행 후 메모리에서 필터를 필터링해야 할 수도 있습니다.

var queryResult =
    groups_to_query
    .SelectMany(g => g.Contacts)
    .Where(c => c.ID == Guid.Empty)
    .Select(c => new {
        contact = c,
        detailIDs = c.ContactDetails.Select(d => d.ID)
    }).ToList();

var contacts =
    queryResult
    .Where(r => r.detailIDs.All(id => id == Guid.Empty))
    .Select(r => r.contact);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top