2009-05-27 5 views
4

다음과 같은 코드가 있습니다.Entity Framework 탐색 속성에서 LINQ 식을 만드는 방법

Expression<Func<Subscription, Service>> service2= subscription => (from relationship in subscription.ChildRelationships 
    select relationship.SecondService).FirstOrDefault(); 

그러면 엔티티 프레임 워크와 함께 쿼리의 일부로 나중에 사용할 수있는 식을 만듭니다. 실제 코드에는 where 절이 있지만 읽기 쉽도록 생략했습니다. 이것은 잘 작동하고 테스트를 위해 사용하고있는 LINQPad에서 실행할 수 있습니다.

코드를 다음과 같이 변경하면

Expression<Func<Subscription, IQueryable<Service>>> service2= subscription => (from relationship in subscription.ChildRelationships 
    select relationship.SecondService); 

더 이상 컴파일되지 않고 다음 오류가 발생합니다.

Cannot convert lambda expression to delegate type 'System.Func<Farmworks.Data.Subscription,System.Linq.IQueryable<Farmworks.Data.Service>>' because some of the return types in the block are not implicitly convertible to the delegate return type

탐색 속성 인 ChildRelationships가 구현하지 않았기 때문입니다 IQueryable. 실제로는 IEnumerable을 구현하지만 EntityCollection 유형이지만 EF와 작동하는 표현식을 작성하는 데는 적합하지 않습니다.

두 번째 코드 블록이 작동하지 않는 이유를 이해하고이를 다시 작성하는 방법을 알고 싶습니다. 또한 퍼즐의 첫 번째 블록이 작동하는 이유는 무엇입니까? 또한 ChildRelationships 탐색 속성을 사용하지만 EF와 함께 작동하는 표현식에 문제가 없습니다.

누구든지 어떤 빛을 낼 수 있습니까?

답변

0

나는 CompiledQuery 클래스가이 경우에 당신을 도울 수 있습니다 생각 :

Expression<Func<Subscription, IQueryable<Service>>> service2 = 
    CompiledQuery.Compile( 
     subscription => (
      from relationship in subscription.ChildRelationships 
      select relationship.SecondService 
     ) 
    ); 
1

문제는 FirstOrDefault 어떻게 든 식 일을 만드는 것이 아니다; 말하듯이 ChildRelationships 자체가 IQueryable을 구현하지는 않습니다. 귀하의 필요에 따라 두 가지 방법으로이를 해결할 수 있습니다.

IEnumerable.AsQueryable 메서드를 사용할 수 있습니다. 서비스가 컨텍스트에서 이미로드 된 경우이 방법이 가장 좋습니다.

서비스가로드되지 않은 경우 필요에 따라로드 또는 포함 메서드를 사용하여 해당 시간에로드 한 다음 위의 솔루션을 사용할 수 있습니다.

Expression<Func<Subscription, MyEntities, IQueryable<Service>>> service2 = 
    (subscription, context) => (
    from s in context.Subscriptions // here is the IQueryable 
    where s.Id == subscription.Id 
    from relationship in s.ChildRelationships 
    select relationship.SecondService); 
+0

코드를 시도했지만 다음 코드가 있습니다. 소스 형식이 'System.Data.Objects.DataClasses.EntityCollection '. 'SelectMany'호출에서 형식 유추가 실패했습니다. – GiddyUpHorsey

+0

그래, 나는 여기에 어떤 타입이 있는지 깨닫고있다. 내 대답을 다시 쓰겠습니다. –

0

당신이 < 서비스에 IQueryable로 그것을 필요하십니까> : 당신이 당신의 ObjectContext는에 대한 참조가있는 경우

, 당신은 된 IQueryable을 구현 않는하여 ObjectQuery를 사용할 수 있습니까? 나는 select가 IEnumerable < Service>를 리턴한다고 생각한다. LINQ는 IEnumerable에서 직접 작동하므로 service2를 Expression < Func < Subscription, IEnumerable < 서비스 >>>로 선언하면됩니다.