2011-05-07 5 views
2

최근 Entity에서 네비게이션 속성에 Iqueryable, 을 구현하지 않은 이상한 것으로 나타났습니다. 하나의 엔티티를 검색 한 다음 탐색 속성에서 연산자를 연결하면 많은 (항목 당 1 개) 호출이 발생할 수 있습니다. 데이터베이스, 생성 된 코드에서 하나의 큰 쿼리에 하위 쿼리 결과 (가능한 경우)가 하나만있는 큰 쿼리를 갖는 경우가 있습니다.하위 쿼리 내의 엔티티에 대한 linq의 탐색 속성이 IQueryable을 구현하지 않는 이유는 무엇입니까?

그러나 하위 쿼리에서 사용할 수있는 오버로드가 하위 쿼리 외부의 탐색 속성에서 호출되는 것과 동일하기 때문에 어떻게 작동하는지 궁금합니다. 질문 1 : 내 생각 엔 IEnuerable에 있더라도 모든 호출 자체가 where로 전달 된 표현식의 일부인 반면, where 및 parsed에서 생성 된 단일 표현식 트리로 빌드되며 별도의 표현식이 아닙니다. 그 자체로 표현이 아니기 때문에), 맞습니까?

Qestion 2 : # 1이 올바른 경우 런타임에 대리인에서만 수행 할 수있는 식 외부에서 코드를 만드는 경우 어떻게 작동합니까 (예 : PredicateExprEntityTwo.Compile을 전달하면 어떻게 작동합니까? 컴파일러가 컴파일 타임에 표현식 내에서 func의 사용법을 알지 못하기 때문에 런타임에 컴파일 및 실패하지 않겠습니까?

질문 3 : # 1과 # 2 올바른,이 디자인의 장점 대 거기에 표현을 복용 무엇입니까? 내가 만난 단점은 비즈니스 유효성 검사를 위해 비즈니스 논리가있는 술어 집합을 가지고 같은 유형의 엔터티를 필터링하기 위해 통합 된 것입니다. 프로그램의 많은 장소, 그러나 나는 그것을 서브 쿼리에 사용할 수 있습니다. # 2가 맞다고 가정하면 같은 것을 재사용하는 것이 불가능할 수 있습니다.

질문이 혼란 스럽지만 지난주에 IEnumerables 오버로드가 서브 쿼리에서 호출되었지만 출력으로 단일 EF 쿼리가 있었음을 알게되어 유감스럽게 생각합니다. 작업.

public class Class1 
{ 
    void Test() 
    { 
     Func<Entity1, bool> PredicateFuncEntityOne = i => i.Id == 2; 
     Expression<Func<Entity1, bool>> PredicateExprEntityOne = i => i.Id == 2; 
     Func<Entity2, bool> PredicateFuncEntityTwo = i => i.Id == 2; 
     Expression<Func<Entity2, bool>> PredicateExprEntityTwo = i => i.Id == 2; 
     using (var Context = new TestModelContainer()) 
     { 
      // Works as this expects an expression 
      var q1 = Context.Entity1Set.Where(PredicateExprEntityOne); 
      // Works but would call the IEnumerable version 
      var q2 = Context.Entity1Set.Where(PredicateFuncEntityOne); 
      // This compiles, any on item.Entity2 expects a func on IEnumerable, not IQueryable overload 
      var q3 = Context.Entity1Set.Where(item => item.Entity2.Any(PredicateFuncEntityTwo)); 
      // This fails for the reason mentioned above 
      var q4 = Context.Entity1Set.Where(item => item.Entity2.Any(PredicateExprEntityTwo)); 
      // Does this work and if so how is it possible? 
      var q5 = Context.Entity1Set.Where(item => item.Entity2.Any(PredicateExprEntityTwo.Compile())); 
     } 
    } 
} 

답변

0

1 : 나도 이것이 옳다고 생각합니다.

Q2 : 예, Func 또는 대리자를 식에 전달하면 쿼리 컴파일이 실패합니다.

Q3에 대해 확실하지 않습니다.

하지만 얼마 전에 EF에서 놀면서 비슷한 문제가있었습니다. 그리고 그 관계형 속성을 IQueryable에 캐스팅하고 Expressions가 supprisingly working을 호출하는 것을 발견했습니다. 그러나 우연 일 수도 있습니다.

+0

안녕하세요, 이것은 내 질문에 실제로 대답하지 않는 것이지요. 주변에서 몇 가지 강력한 프로그램 디자인 결정을 토대로하고 있으며 테스트 할 수있는 동안 사양 수준 응답을 찾고 있습니다. 그것은 오히려 내가 왜 뭔가를 놓치고 있는지 궁금해서 IQueryable로 표시하는 것에 비해 직관적 인 카운터입니다.) –

관련 문제