2009-04-27 3 views
44

를로드하지() 메소드를 포함, (가) 포함() 메소드는 더 이상 예를 들어, 작업입니다 더 많거나 적은 같은 일이 같은 결과를 얻을 수하지만, 더 함께 할 에 더 자세한 방법을 시도 Linq에 - 투 - 엔티티 내가 조인을 사용하는 경우

+0

왜 그렇게 생각하십니까? 실행 후 값을 줄이지 않습니까? – pocheptsov

+0

"속성"이 포함 문자열로 전달되는 것이 아니라고 추측합니다. 이것은 질문의 가장 중요한 부분을 생략했음을 의미합니다. 또한, 나는 왜 당신이 조인을 사용하고 있는지 질문합니다; 탐색 속성은 일반적으로 Entity Framework에서 관계를 트래버스하는 올바른 방법입니다. –

+0

pocheptsov - Proeprties.IsLoaded가 거짓이므로 속성이로드되지 않았다는 것을 알고 있습니다. 안녕하세요 크레이그 - '속성'이 올바른 문자열입니다. 조인은 다른 탐색 속성 항목에 있습니다. Item 객체 (Collection.ID)의 속성에 대한 값을 가지고 있기 때문에 조인이 있습니다. 그러나 관련된 엔티티를 원합니다. Lee –

답변

54

업데이트 : 사실 최근에 저는 이것을 다루는 또 다른 팁을 추가했으며 대체 솔루션을 제공합니다. 아이디어는 포함의 사용을 지연하는 것입니다() 쿼리가 끝날 때까지, 자세한 내용은이를 참조하십시오 Tip 22 - How to make include really include


이 알려진 제한을 엔티티 프레임 워크에 포함 사용하는 경우(). 특정 작업은 포함과 함께 지원되지 않습니다. 실체와 속성의 관계가있는 경우

var results = 
    from e in dc.Entities //Notice no include 
    join i in dc.Items on e.ID equals i.Member.ID 
    where (i.Collection.ID == collectionID) 
    select new {Entity = e, Properties = e.Properties}; 

이 속성을 다시 가져올 것이며, :

당신이 이런 식으로 뭔가를 시도해야이 문제를 해결하려면, 그 제한 사항에 대한 하나에 실행 한 수 것 같은데 많은 (많은 것에 아니지만 많은)에 하나는 각 결과 익명의 유형에 같은 값을 가지고 있음을 발견 할 것이다 :

anonType.Entity.Properties 
anonType.Properties 

이는 엔티티 프레임 워크라는 관계 픽스의 기능의 부작용이다.

더 많은 정보는 EF Tips seriesTip 1을 참조하십시오.

+0

대단히 감사합니다. 도움을 주셔서 감사합니다. – ChrisHDog

+1

아직도 그렇습니까? "새 항목 선택 {...};" .Include() 문이 작동하지 않습니다? – grimus

+0

@grimus,'Include'에서 전체 쿼리를 래핑하는 것은 쿼리에 의해 생성 된 요소 유형이 엔티티 유형이 아닌 경우 현재 작동하지 않는 것처럼 보입니다. 그러나'select' 절 안에서 탐색 속성 값을 얻으려는 원래의 제안은 이것을 우회하는 것으로 보인다. – Sam

0

작동) (포함] 가입 datacalls :

var mydata = from e in dc.Entities 
      join i in dc.Items 
       on e.ID equals i.Member.ID 
      where (i.Collection.ID == collectionID) 
      select e; 

foreach (Entity ent in mydata) { 
    if(!ent.Properties.IsLoaded) { ent.Properties.Load(); } 
} 

그래도 (예기치 않은) 동일한 결과가 발생합니까?

편집 : 첫 번째 문장이 잘못되어 변경되었습니다. 포인터 주석 주셔서 감사합니다!

+0

그건 전혀 똑같은 것이 아닙니다. 귀하의 코드는 n + 1 개의 데이터베이스 쿼리가되며, n은 검색된 행의 수입니다. 1 데이터베이스 쿼리에 결과를 포함하십시오. –

+0

나는 똑같은 일을하지 않는다는 것을 안다 - 나는 똑같은 결과로 끝날 것이라고 말하는 것은 엉성한 방법이었다. 이 작업을 수행하는 주된 이유는이 방식으로로드 된 모든 등록 정보가 있는지를 확인하는 것이 었습니다. 그렇지 않은 경우 문제는 .Include() 구문이 아니라 데이터 (연결된 속성 레코드가 누락 된 경우 등) 일 수 있습니다. –

+0

안녕하세요 토마스 Properties.Load()를 사용하여 Properties를로드하면 올바르게로드됩니다. 내가 조인을 포함하지 않는 쿼리에 포함 ("속성")을 사용하는 경우 (예 :: dc.Entities.Include ("Properties")에서 여기서 (e.ID = id) 선택 전자; 정상적으로 작동합니다. Lee –

4

그래서 "Item.Member"(즉, 탐색의 다른 쪽 끝)과 관련된 "Entity"의 탐색 속성 이름은 무엇입니까? 조인 대신에 이것을 사용해야합니다. "실체"일의 중요도와 회원이라는 속성을 추가하고 예를 들어, 회원이 많은의 카디 낼 리티 항목이라는 속성을 가지고, 당신이 할 수 있습니다 :

from e in dc.Entities.Include("Properties") 
where e.Member.Items.Any(i => i.Collection.ID == collectionID) 
select e 

를 내가의 속성을 추측하고있어 여기에 모델이 있지만 일반적인 아이디어가 있어야합니다. 대부분의 경우 LINQ to Entities에서 조인을 사용하면 잘못된 번호가입니다. 네비게이션 속성이 올바르게 설정되지 않았거나 사용하지 않았다고 제안하기 때문입니다.

20

이 시도 :

var query = (ObjectQuery<Entities>)(from e in dc.Entities 
      join i in dc.Items on e.ID equals i.Member.ID 
      where (i.Collection.ID == collectionID) 
      select e) 

return query.Include("Properties") 
1

그래서, 내가 여기에 파티에 늦게 오전 실현, 그러나 나는 내 연구 결과를 추가 할 거라고 생각했다.이것은 Alex James의 게시물에 대한 코멘트 일 것입니다.하지만 평판이 없으므로 여기로 가야합니다.

내 대답은 : 당신이 의도 한 것처럼 전혀 작동하지 않는 것 같습니다. Alex James는 두 가지 흥미로운 솔루션을 제공합니다. 그러나 SQL을 확인하고 시도해 보면 무서운 것입니다.

내가 작업 된 예는 다음과 같습니다

 var theRelease = from release in context.Releases 
         where release.Name == "Hello World" 
         select release; 

     var allProductionVersions = from prodVer in context.ProductionVersions 
            where prodVer.Status == 1 
            select prodVer; 

     var combined = (from release in theRelease 
         join p in allProductionVersions on release.Id equals p.ReleaseID 
         select release).Include(release => release.ProductionVersions);    

     var allProductionsForChosenRelease = combined.ToList(); 

이 두 사례의 단순 다음과 같습니다. (가) 포함 없이는 완벽하게 존경 SQL을 생성합니다

SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Name] AS [Name] 
    FROM [dbo].[Releases] AS [Extent1] 
    INNER JOIN [dbo].[ProductionVersions] AS [Extent2] ON [Extent1].[Id] = [Extent2].[ReleaseID] 
    WHERE ('Hello World' = [Extent1].[Name]) AND (1 = [Extent2].[Status]) 

그러나 OMG와 함께 :

SELECT 
[Project1].[Id1] AS [Id], 
[Project1].[Id] AS [Id1], 
[Project1].[Name] AS [Name], 
[Project1].[C1] AS [C1], 
[Project1].[Id2] AS [Id2], 
[Project1].[Status] AS [Status], 
[Project1].[ReleaseID] AS [ReleaseID] 
FROM (SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Name] AS [Name], 
    [Extent2].[Id] AS [Id1], 
    [Extent3].[Id] AS [Id2], 
    [Extent3].[Status] AS [Status], 
    [Extent3].[ReleaseID] AS [ReleaseID], 
    CASE WHEN ([Extent3].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1] 
    FROM [dbo].[Releases] AS [Extent1] 
    INNER JOIN [dbo].[ProductionVersions] AS [Extent2] ON [Extent1].[Id] = [Extent2].[ReleaseID] 
    LEFT OUTER JOIN [dbo].[ProductionVersions] AS [Extent3] ON [Extent1].[Id] = [Extent3].[ReleaseID] 
    WHERE ('Hello World' = [Extent1].[Name]) AND (1 = [Extent2].[Status]) 
) AS [Project1] 
ORDER BY [Project1].[Id1] ASC, [Project1].[Id] ASC, [Project1].[C1] ASC 

전체 쓰레기. 여기서 주목해야 할 핵심은 status = 1로 제한되지 않은 테이블의 외부 조인 된 버전을 반환한다는 사실입니다. 잘못된 데이터에

이 결과가 반환되는 : 2의 상태가 우리의 제한에도 불구하고,이 반환되고 있음을

Id Id1 Name  C1 Id2 Status ReleaseID 
2 1 Hello World 1 1 2  1 
2 1 Hello World 1 2 1  1 

참고. 단순히 작동하지 않습니다. 만약 내가 어딘가에 잘못 갔다면, Linq의 조롱 거리가되어 버렸기 때문에, 알아 내서 기뻐할 것입니다. 나는 그 아이디어가 마음에 들지만, 그 실행은 순간에 쓸모없는 것 같지 않습니다.


은 호기심, 나는 시도 LinqToSQL DBML 오히려 위의 혼란을 생산 LinqToEntities의 edmx 이상 :

SELECT [t0].[Id], [t0].[Name], [t2].[Id] AS [Id2], [t2].[Status], [t2].[ReleaseID], (
    SELECT COUNT(*) 
    FROM [dbo].[ProductionVersions] AS [t3] 
    WHERE [t3].[ReleaseID] = [t0].[Id] 
    ) AS [value] 
FROM [dbo].[Releases] AS [t0] 
INNER JOIN [dbo].[ProductionVersions] AS [t1] ON [t0].[Id] = [t1].[ReleaseID] 
LEFT OUTER JOIN [dbo].[ProductionVersions] AS [t2] ON [t2].[ReleaseID] = [t0].[Id] 
WHERE ([t0].[Name] = @p0) AND ([t1].[Status] = @p1) 
ORDER BY [t0].[Id], [t1].[Id], [t2].[Id] 

약간 더 컴팩트 한 - 이상한 카운트 절, 그러나 전반적으로 동일한 총 FAIL.

실제 비즈니스 응용 프로그램에서이 물건을 사용한 사람이 있습니까? 나는 정말로 궁금해하기 시작했습니다 ... 제가 정말로 Linq을 원한다고 말하고 싶습니다.

관련 문제