Entity Framework 4.0 Database First 및 ASP.NET 4 Web Forms 시작 - 6부

작성자: Tom Dykstra

Contoso University 샘플 웹 애플리케이션은 Entity Framework 4.0 및 Visual Studio 2010을 사용하여 ASP.NET Web Forms 애플리케이션을 만드는 방법을 보여 줍니다. 자습서 시리즈에 대한 자세한 내용은 시리즈의 첫 번째 자습서를 참조하세요.

계층당 하나의 테이블 상속 구현

이전 자습서에서는 관계를 추가하고 삭제하고 기존 엔터티와 관계가 있는 새 엔터티를 추가하여 관련 데이터를 사용했습니다. 이 자습서에서는 데이터 모델에서 상속을 구현하는 방법을 보여 줍니다.

개체 지향 프로그래밍에서는 상속을 사용하여 관련 클래스를 더 쉽게 작업할 수 있습니다. 예를 들어 기본 클래스에서 파생되는 및 Student 클래스를 Person 만들 Instructor 수 있습니다. Entity Framework의 엔터티 간에 동일한 종류의 상속 구조를 만들 수 있습니다.

자습서의 이 부분에서는 새 웹 페이지를 만들지 않습니다. 대신 데이터 모델에 파생 엔터티를 추가하고 새 엔터티를 사용하도록 기존 페이지를 수정합니다.

계층별 테이블 및 형식별 테이블 상속

데이터베이스는 관련 개체에 대한 정보를 한 테이블 또는 여러 테이블에 저장할 수 있습니다. 예를 들어 데이터베이스에서 School 테이블에는 단일 테이블의 Person 학생 및 강사에 대한 정보가 포함됩니다. 일부 열은 강사(HireDate)에만 적용되고 일부는 학생(EnrollmentDate)에만 적용되고 일부는 둘 다(LastName, FirstName)에만 적용됩니다.

image11

엔터티에서 상속되는 엔터티 및 Student 를 만들 Instructor 도록 Entity Framework를 Person 구성할 수 있습니다. 단일 데이터베이스 테이블에서 엔터티 상속 구조를 생성하는 이 패턴을 TPH( 테이블 단위 계층 ) 상속이라고 합니다.

과정의 경우 데이터베이스는 School 다른 패턴을 사용합니다. 온라인 과정 및 현장 과정은 각각 테이블을 가리키는 Course 외래 키가 있는 별도의 테이블에 저장됩니다. 두 과정 유형에 공통적인 정보는 테이블에만 Course 저장됩니다.

image12

엔터티와 OnsiteCourse 엔터티가 엔터티에서 Course 상속되도록 OnlineCourse Entity Framework 데이터 모델을 구성할 수 있습니다. 각 형식에 대한 별도의 테이블에서 엔터티 상속 구조를 생성하는 이 패턴은 각 개별 테이블이 모든 형식에 공통된 데이터를 저장하는 테이블을 다시 참조하는 것을 TPT( 형식별 테이블 ) 상속이라고 합니다.

TPH 상속 패턴은 일반적으로 TPT 상속 패턴보다 Entity Framework에서 더 나은 성능을 제공합니다. TPT 패턴으로 인해 복잡한 조인 쿼리가 발생할 수 있기 때문입니다. 이 연습에서는 TPH 상속을 구현하는 방법을 보여 줍니다. 다음 단계를 수행하여 이 작업을 수행합니다.

  • 에서 Person파생되는 및 Student 엔터티 형식을 만듭니 Instructor 다.
  • 파생 엔터티와 관련된 속성을 엔터티에서 Person 파생 엔터티로 이동합니다.
  • 파생 형식의 속성에 대한 제약 조건을 설정합니다.
  • 엔터티를 Person 추상 엔터티로 만듭니다.
  • 행이 파생 형식을 나타내는지 여부를 결정하는 방법을 지정하는 조건으로 각 파생 엔터티 PersonPerson 테이블에 매핑합니다.

강사 및 학생 엔터티 추가

SchoolModel.edmx 파일을 열고 디자이너에서 비어 있는 영역을 마우스 오른쪽 단추로 클릭하고 추가를 선택한 다음 엔터티를 선택합니다.

image01

엔터티 추가 대화 상자에서 엔터티 Instructor 의 이름을 지정하고 기본 형식 옵션을 로 Person설정합니다.

image02

확인을 클릭합니다. 디자이너는 엔터티에서 파생되는 엔터티를 Person 만듭니다Instructor. 새 엔터티에는 아직 속성이 없습니다.

image03

프로시저를 반복하여 에서 Person파생되는 엔터티를 만듭니 Student 다.

강사만 고용 날짜를 가지므로 해당 속성을 엔터티에서 Person 엔터티로 Instructor 이동해야 합니다. 엔터티에서 Person 속성을 마우스 오른쪽 단추로 HireDate 클릭하고 잘라내기를 클릭합니다. 그런 다음 엔터티에서 속성을 마우스 오른쪽 단추로 Instructor 클릭하고 붙여넣기를 클릭합니다.

image04

엔터티의 Instructor 고용 날짜는 null일 수 없습니다. 속성을 마우스 오른쪽 단추로 HireDate 클릭하고 속성을 클릭한 다음 속성 창에서 으로 변경 Nullable 합니다 False.

image05

프로시저를 반복하여 엔터티에서 Person 엔터티로 Student 속성을 이동합니다EnrollmentDate. 속성에 대해서도 를 FalseEnrollmentDate 로 설정 Nullable 해야 합니다.

엔터티에 Person 공통 Instructor 적인 속성과 Student 엔터티(이동하지 않는 탐색 속성 제외)만 있으므로 엔터티는 상속 구조에서 기본 엔터티로만 사용할 수 있습니다. 따라서 독립 엔터티로 처리되지 않도록 해야 합니다. 엔터티를 마우스 오른쪽 단추로 Person 클릭하고 속성을 선택한 다음 속성 창에서 Abstract 속성의 값을 True로 변경합니다.

image06

강사 및 학생 엔터티를 Person 테이블에 매핑

이제 데이터베이스의 엔터티와 Student 엔터티를 구분 Instructor 하는 방법을 Entity Framework에 알려야 합니다.

엔터티를 마우스 오른쪽 단추로 Instructor 클릭하고 테이블 매핑을 선택합니다. 매핑 세부 정보 창에서 테이블 또는 보기 추가를 클릭하고 사용자를 선택합니다.

image07

조건 추가를 클릭한 다음, HireDate를 선택합니다.

image09

연산자 를 Is로, Value/PropertyNull이 아님으로 변경합니다.

image10

열이 null이 Students 아닌 경우 이 엔터티가 테이블에 매핑되도록 Person 지정하여 엔터티에 대한 프로시저를 EnrollmentDate 반복합니다. 그런 다음 데이터 모델을 저장하고 닫습니다.

새 엔터티를 클래스로 만들고 디자이너에서 사용할 수 있도록 프로젝트를 빌드합니다.

강사 및 학생 엔터티 사용

학생 및 강사 데이터로 작동하는 웹 페이지를 만들 때 엔터티 집합에 Person 데이터를 바인딩하고 또는 EnrollmentDate 속성을 필터링하여 반환된 HireDate 데이터를 학생 또는 강사로 제한했습니다. 그러나 이제 각 데이터 원본 컨트롤을 엔터티 집합에 Person 바인딩할 때 또는 Instructor 엔터티 형식만 Student 선택하도록 지정할 수 있습니다. Entity Framework는 엔터티 집합에서 Person 학생과 강사를 구분하는 방법을 알고 있으므로 수동으로 입력한 속성 설정을 제거 Where 하여 이를 수행할 수 있습니다.

Visual Studio Designer 다음 예제와 같이 마법사의 Configure Data SourceEntityTypeFilter 드롭다운 상자에서 컨트롤이 선택해야 하는 엔터티 형식 EntityDataSource 을 지정할 수 있습니다.

image13

다음 예제와 같이 속성 창에서 더 이상 필요하지 않은 절 값을 제거할 Where 수 있습니다.

image14

그러나 특성을 사용하도록 ContextTypeName 컨트롤에 대한 EntityDataSource 태그를 변경했으므로 이미 만든 컨트롤에서 EntityDataSource데이터 원본 구성 마법사를 실행할 수 없습니다. 따라서 대신 태그를 변경하여 필요한 내용을 변경합니다.

Students.aspx 페이지를 엽니다. 컨트롤에서 StudentsEntityDataSource 특성을 제거하고 Where 특성을 추가 EntityTypeFilter="Student" 합니다. 태그는 이제 다음 예제와 유사합니다.

<asp:EntityDataSource ID="StudentsEntityDataSource" runat="server" 
        ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
        EntitySetName="People" EntityTypeFilter="Student"
        Include="StudentGrades"
        EnableDelete="True" EnableUpdate="True" 
        OrderBy="it.LastName" >
    </asp:EntityDataSource>

EntityTypeFilter 특성을 설정하면 컨트롤이 EntityDataSource 지정된 엔터티 형식만 선택하게 됩니다. 및 Instructor 엔터티 형식을 모두 Student 검색하려는 경우 이 특성을 설정하지 않습니다. (읽기 전용 데이터 액세스에 컨트롤을 사용하는 경우에만 하나의 EntityDataSource 컨트롤로 여러 엔터티 형식을 검색할 수 있습니다. 컨트롤을 사용하여 엔터티를 EntityDataSource 삽입, 업데이트 또는 삭제하는 경우 엔터티가 바인딩된 엔터티가 여러 형식을 포함할 수 있는 경우 하나의 엔터티 형식으로만 작업할 수 있으며 이 특성을 설정해야 합니다.)

속성을 완전히 제거하는 대신 엔터티를 선택하는 Student 특성의 Where 일부만 제거하는 것을 제외하고 컨트롤에 대한 SearchEntityDataSource 프로시저를 반복합니다. 이제 컨트롤의 여는 태그가 다음 예제와 유사합니다.

<asp:EntityDataSource ID="SearchEntityDataSource" runat="server" 
        ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" 
        EntitySetName="People" EntityTypeFilter="Student"
        Where="it.FirstMidName Like '%' + @StudentName + '%' or it.LastName Like '%' + @StudentName + '%'" >

페이지를 실행하여 이전과 마찬가지로 여전히 작동하는지 확인합니다.

image15

이전 자습서에서 만든 다음 페이지를 업데이트하여 엔터티 대신 PersonStudent 엔터티와 Instructor 엔터티를 사용하도록 한 다음, 실행하여 이전과 같이 작동하는지 확인합니다.

  • StudentsAdd.aspx에서 컨트롤에 를 추가 EntityTypeFilter="Student" 합니다StudentsEntityDataSource. 태그는 이제 다음 예제와 유사합니다.

    <asp:EntityDataSource ID="StudentsEntityDataSource" runat="server" 
            ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
            EntitySetName="People" EntityTypeFilter="Student"
            EnableInsert="True" 
        </asp:EntityDataSource>
    

    image16

  • About.aspx에서 컨트롤에 를 추가하고 EntityTypeFilter="Student"StudentStatisticsEntityDataSource 제거합니다Where="it.EnrollmentDate is not null". 태그는 이제 다음 예제와 유사합니다.

    <asp:EntityDataSource ID="StudentStatisticsEntityDataSource" runat="server" 
            ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" 
            EntitySetName="People" EntityTypeFilter="Student"
            Select="it.EnrollmentDate, Count(it.EnrollmentDate) AS NumberOfStudents"
            OrderBy="it.EnrollmentDate" GroupBy="it.EnrollmentDate" >
        </asp:EntityDataSource>
    

    image17

  • Instructors.aspxInstructorsCourses.aspx에서 컨트롤에 InstructorsEntityDataSource 를 추가하고 EntityTypeFilter="Instructor" 를 제거Where="it.HireDate is not null"합니다. 이제 Instructors.aspx 의 태그는 다음 예제와 유사합니다.

    <asp:EntityDataSource ID="InstructorsEntityDataSource" runat="server" 
                ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="false"
                EntitySetName="People" EntityTypeFilter="Instructor" 
                Include="OfficeAssignment" 
                EnableUpdate="True">
            </asp:EntityDataSource>
    

    image18

    이제 InstructorsCourses.aspx 의 태그가 다음 예제와 유사합니다.

    <asp:EntityDataSource ID="InstructorsEntityDataSource" runat="server" 
            ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" 
            EntitySetName="People" EntityTypeFilter="Instructor" 
            Select="it.LastName + ',' + it.FirstMidName AS Name, it.PersonID">
        </asp:EntityDataSource>
    

    image19

이러한 변경으로 인해 여러 가지 방법으로 Contoso University 애플리케이션의 유지 관리 효율성이 향상되었습니다. 선택 및 유효성 검사 논리를 UI 계층(.aspx 태그)에서 벗어나 데이터 액세스 계층의 필수적인 부분으로 만들었습니다. 이렇게 하면 나중에 데이터베이스 스키마 또는 데이터 모델을 변경할 수 있는 변경 내용으로부터 애플리케이션 코드를 격리할 수 있습니다. 예를 들어 학생이 교사의 보조원으로 고용될 수 있으므로 고용 날짜를 얻을 수 있다고 결정할 수 있습니다. 그런 다음 새 속성을 추가하여 학생을 강사와 차별화하고 데이터 모델을 업데이트할 수 있습니다. 학생 고용 날짜를 표시하려는 경우를 제외하고는 웹 애플리케이션의 코드를 변경할 필요가 없습니다. 및 Student 엔터티를 추가하는 Instructor 또 다른 이점은 코드가 실제로 학생 또는 강사인 개체를 참조할 Person 때보다 쉽게 이해할 수 있다는 것입니다.

이제 Entity Framework에서 상속 패턴을 구현하는 한 가지 방법을 살펴보았습니다. 다음 자습서에서는 Entity Framework가 데이터베이스에 액세스하는 방법을 보다 자세히 제어하기 위해 저장 프로시저를 사용하는 방법을 알아봅니다.