2017-11-28 21 views
1

를 쿼리에 하나의 LINQ 내에서 두 개의 구조적으로 호환되지 않는 초기화에 표시되지만 다음과 같은 오류 가져옵니다매핑 가입 - 유형 'CarDTO은'엔티티 내가 <code>left join</code>의 오른쪽에서 <code>CarDTO</code>로 매핑하는 것을 시도하고있다

The type 'CarDTO' appears in two structurally incompatible initializations within a single LINQ to Entities query. A type can be initialized in two places in the same query, but only if the same properties are set in both places and those properties are set in the same order.

나는 self left join를 만들기 위해 노력하고 내 쿼리는 다음과 같습니다

var query = from left in db.Cars 
    join right in db.Cars on left.id_Base equals right.ID into rightGrouped 
    from rightGr in rightGrouped.DefaultIfEmpty() 
    select new CarDTO() 
    { 
     ID = left.ID, 
     Description = left.DisplayName, 
     Name = left.Name, 
     IsSystem = left != null ? left.Template.isSystem : (byte?)null, 
     IdBase = left.id_Base,        
     InnerCar = new CarDTO() 
     { 
      ID = rightGr.ID, 
      Description = rightGr.DisplayName, 
      Name = rightGr.Name, 
      IsSystem = rightGr != null ? rightGr.Template.isSystem : (byte?)null, 
      IdBase = rightGr.id_Base, 
      InnerCar = new CarDTO()         
     }        
    }; 

나는 다음과 같은 행을 변경하는 경우 InnerCar = new CarDTO()InnerCar = null에, 다음 내가 추적을 얻을 오류 :

Unable to create a null constant value of type 'CarDTO'. Only entity types, enumeration types or primitive types are supported in this context.`

아무도 내가 뭘 잘못하고 있는지 알아?

+0

을 마지막 줄에서'InnerCar = new CarDTO()'를'InnerCar = null'으로 변경해보십시오. – Evk

+0

@Evk 조언을 해주셔서 감사합니다. ''CarDTO '유형의 널 (NULL) 상수 값을 생성 할 수 없습니다.'오류가 발생합니다. 이 문맥에서 엔티티 타입, 열거 형 또는 기본 타입 만 지원됩니다. ' – StepUp

+0

'InnerCar '(예 : 익명 타입 사용)에 다른 유형을 사용하는 것 외에는 다른 방법이없는 것 같습니다. – Evk

답변

1

오류 메시지는 동일한 식의 동일한 유형 (이 경우 CarDto)의 모든 초기화가 규칙을 따르기를 기대한다고 설명합니다. 각 초기화에서 동일한 속성이 동일한 순서로 설정되어야합니다. 3 개의 초기화가 있으므로 코드가이 규칙을 위반합니다. 그들 중 2 명은 같은 순서로 동일한 속성을 설정하지만, 세 번째 (마지막 InnerCar = new CarDTO())는 그렇지 않습니다.

이 규칙을 만족시키기 위해 InnerCar.InnerCar 초기화에서 사용할 수있는 유일한 값은 (재귀 적 정의 때문에) null입니다. 그러나 EF는 임의의 유형의 상수 값을 생성 할 수 없기 때문에 그렇게 할 수 없습니다 (그러한 것을 SQL로 변환하는 방법을 알지 못합니다).

재귀 유형으로 이것을 수행하는 것은 불가능합니다. 대신 InnerCar에 다른 유형을 사용해야합니다. 예를 들어 다음과 같은 익명 형식을 사용할 수 있습니다.

select new 
{ 
    ID = left.ID, 
    Description = left.DisplayName, 
    Name = left.Name, 
    IsSystem = left != null ? left.Template.isSystem : (byte?)null, 
    IdBase = left.id_Base,        
    InnerCar = new 
    { 
     ID = rightGr.ID, 
     Description = rightGr.DisplayName, 
     Name = rightGr.Name, 
     IsSystem = rightGr != null ? rightGr.Template.isSystem : (byte?)null, 
     IdBase = rightGr.id_Base        
    }        
}; 

두 익명 형식이 다르기 때문에이 방법이 효과적입니다. 첫 번째 속성에는 InnerCar을 포함한 6 개의 속성이 있고 두 번째 속성에는 InnerCar이없는 5 개의 속성이 있습니다. 물론 유형을 익명으로 지정하는 것은 필수 조건이 아닙니다.

또한 바로이 구조 평평하게 할 수

: 당신이 그런 매핑을 수행하고, 어떤 다른 필터링 \ 페이징 \ 완료 한 후

select new 
{ 
    LeftID = left.ID, 
    RightID = rightGr.ID, 
    // etc 
}; 

- 구체화 한 후 유형으로 변환 :

// query here is complete 
var result = query.AsEnumerable().Select(c => { 
    new CarDto { 
     ID = c.ID, 
     Description = c.Description, 
     // etc 
    } 
}); 
+0

익명 형식의 솔루션을 확인할 수 없지만 해결할 수 있다고 생각합니다. :). – StepUp

+1

예, 테스트 할 것입니다. :) – Evk