2011-12-13 4 views
1

http://www.sqlteam.com/article/implementing-table-inheritance-in-sql-server에 나와있는 테이블 상속 기능을 구현했습니다.포함/결합 문제가있는 Entity Framework

모든 외래 키와 제약 조건이 적용됩니다.

이제 모델이 다음과 같이 보이는 (모든 EF 특정 특성 등이없는) 사용자, 학생, 교사 및 학부모를 끌어 오기 위해 Entity Framework를 사용하고 있습니다.

public partial class People : EntityObject 
{ 
    public guid PeopleID { get; set; } 
    public int Age { get; set; } /Added for an example query 
    public PeopleParent Parent { get; set; } 
    public PeopleStudent Student { get; set; } 
    public PeopleTeacher Teacher { get; set; } 
} 

은 지금은 아니, 100 개 이상의 레코드가 25 살에 상관없이 유형의 모든 사람들을 얻을 필요가 있고, 나는 모든 참조 된 데이터를 포함 할. 내가 좋아하는 내 EF 쿼리를 만들 :

IQueryable<People> query = Entities.People.Include("PeopleParent") 
              .Include("PeopleStudent") 
              .Include("PeopleTeacher"); 

query.Where(x => x.Age == 25) 
    .Take(100); 

IEnumerable<People> results = query.ToList(); 

하는 것은 간단한데,하지만 어떤 테이블/entityset은 내가 먼저 포함하도록 설정 대신 올바른 결과를 생산하지 않는 LEFT OUTER JOIN,의 INNER JOIN를 생성했습니다. (내 요구에 대한 잘못된)

생성 TSQL 다음 먼저 INNER JOIN로 사용하고, 내 문제에 대한 soluion이 (가) 있습니다 왜

SELECT 
    [Limit1].[C1] AS [C1], 
    <A bunch of Limit1 Columns> 
FROM (
    SELECT TOP (100) 
    [Extent1].[PeopleID] AS [PeopleID], 
    <A bunch of Extent1 Columns> 
    [Extent2].[PeopleID] AS [PeopleID1], 
    <A bunch of Extent2 Columns> 
    [Extent3].[PeopleID] AS [PeopleID2], 
    <A bunch of Extent3 Columns> 
    [Extent4].[PeopleID] AS [PeopleID3], 
    <A bunch of Extent4 Columns> 
    1 AS [C1] 
    FROM [rets].[People] AS [Extent1] 
    INNER JOIN [rets].[PeopleParent] AS [Extent2] 
    ON [Extent1].[PeopleID] = [Extent2].[PeopleID] 
    LEFT OUTER JOIN [rets].[PeopleStudent] AS [Extent3] 
    ON [Extent1].[PeopleID] = [Extent3].[PeopleID] 
    LEFT OUTER JOIN [rets].[PeopleTeacher] AS [Extent4] 
    ON [Extent1].[PeopleID] = [Extent4].[PeopleID] 
) AS [Limit1] 

?

** UPDATE 1 **

내가 사용하는 가정 라디 Mrnka의 Answer, Linq에와 람다 쿼리의 큰 변화로 인해 두 개의 추가 요구 사항이 있습니다.

질문 : 특정 속성을 가진 특정 인물을 검색하려면 어떻게합니까?

("A"의 학년 모든 학생)

답변 :

context.People.OfType<Student>().Where(s => s.Grade == "A"); 

질문 : 특정 속성을 가지고있는 사람을 검색하려면 어떻게합니까?

대답

(PrimaryFocus = "수학"의 모든 학생 또는 교사) :

List<People> result = new List<People>(); 
result.AddRange(context.People.OfType<Student>() 
           .Where(x => x.PrimaryFocus == "Math") 
           .ToList()); 
result.AddRange(context.People.OfType<Teacher>() 
           .Where(x => x.PrimaryFocus == "Math") 
           .ToList()); 

답변

6

당신이 상속에 대한 기본 EF 지원을 사용해야에 대한 확실한 해결책. 귀하의 경우 TPT inheritance. 상속을 일단 당신은 단순히 호출합니다 :

IEnumerable<People> results = Entities.People 
             .Where(x => x.Age == 25) 
             .Take(100) 
             .ToList(); 

그리고 유일한 충고는 관계가 선택적임을 확인 당신의 솔루션에서 당신에게 등

Student의 경우, Teachers, Parents를 반환합니다 (1 - 0..1) -. 필요한 경우 INNER JOIN을 사용합니다. 선택 사항이며 여전히 INNER JOIN을 사용하는 경우 모델에 버그 또는 기타 문제가있을 수 있습니다.

+0

저는 EF에서 상속 지원을 사용하지 않았습니다. 상속을 사용하기 위해이 "토끼 구멍"을 선택하면,'.Where (x => x.Grade == "A")'를 찾으면 검색에 어떤 영향을 미치게됩니까? 부모님과 교사는 'Grade' 속성 (학생 만)? –

+0

'People'을 검색 할 수는 없지만'Students' :'context.People.OfType () .Where (s => s.Grade == "A")'를 검색 할 수 있습니다. 상속은 까다 롭고 상당한 성능 비용이 있습니다 (.NET 4.5에서는 향상 될 것입니다).하지만 데이터베이스에 가장 적합한 솔루션입니다. –

+0

마지막 질문 하나, 실제 질문을 업데이트했습니다. –