login register Sysop! about ME  
qrcode
    최초 작성일 :    2012년 07월 02일
  최종 수정일 :    2012년 07월 02일
  작성자 :    heykiss
  편집자 :    heykiss (김 도남)
  읽음수 :    40,269

강좌 목록으로 돌아가기

필자의 잡담~

이번 컬럼은 keykiss(김도남)님이 번역해 주셨으며, MVC 애플리케이션을 위해서 엔티티 프레임워크의 데이터 모델을 사용하는 방법에 대해 설명하고 있습니다. 원문은 http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application 입니다.

이 글은 MVC 공식 자습서 중 http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application 의 글을 편역한 내용입니다. 마이크로소프트의 공식 번역 문서가 아니며 태오 사이트 MS 컬럼 번역팀에서 번역한 내용입니다. 그렇기에, 일부 오역이나 오타가 존재할 수 있는 점 미리 양해를 구합니다. 원문에 대한 모든 저작권은 마이크로소프트에 있으며, 컬럼 내용과 관련한 질의 문답 역시 원문 사이트에 문의하시는 것을 추천드립니다.

ASP.NET MVC를 위한 Entity Framework 데이터 모델 만들기

Contoso 대학 웹 응용 프로그램 예제를 통해 엔티티 프레임워크를 사용하여 ASP.NET MVC 응용 프로그램을 만드는 방법을 알아보겠습니다. 예제 응용 프로그램은 가상의 Contoso 대학 웹 사이트입니다. 이 웹 사이트는 학생 입학, 과목 생성, 강사 배정과 같은 기능을 포함하고 있습니다.

이 컬럼 시리즈는 Contoso 대학 예제 응용 프로그램을 만드는 방법을 단계별로 설명하고 있습니다. 여러분은 완성된 응용 프로그램을 다운로드하거나 컬럼을 단계별로 따라하면서 만들 수 있습니다. 컬럼의 예제는 C#으로 설명되어 있습니다. 다운로드가 가능한 예제는 C#과 더불어 Visual Basic 코드도 포함되어 있습니다. 만약 여러분이 이 컬럼과 직접 연관되지 않지만 Entity Framework와 관련된 질문이 있으시면 ASP.NET Entity Framework forum 또는 Entity Framework and LINQ to Entities forum에 질문 하실 수 있습니다.

이 컬럼 시리즈는 여러분이 ASP.NET MVC 응용 프로그램이 비쥬얼 스튜디오에서 어떻게 동작하는지 알고 있다고 가정하고 있습니다. 만약 이 부분이 익숙하지 않으시면 basic ASP.NET MVC Tutorial이 학습을 시작하는 좋은 출발점입니다. 만약 여러분이 ASP.NET 웹 폼 모델을 더 선호하신다면 엔티티 프레임워크 시작하기 그리고 계속해서 엔티티 프레임워크 사용하기를 참조하십시오.

시작하기 전에, 아래의 소프트웨어가 여러분의 컴퓨터에 설치되어 있어야 합니다:

역자 주: 원본 컬럼은 2011년 4월 11에 작성된 글입니다. 현재 가장 최신 버전의 Visual Studio 2012 Release Preview에서 테스트하여 어려움 없이 이 컬럼을 진행할 수 있음을 확인하였고 역자는 VS 2010 버전이 없는 관계로 기존의 스크린샷을 VS 2012 RC 기반으로 변경하였습니다.)

Contoso 대학 웹 응용 프로그램

이 컬럼을 통해 여러분이 만들 응용 프로그램은 간단한 대학교 웹 사이트 입니다.


출처 : http://i1.asp.net/umbraco-beta-media/2577508/Windows-Live-Writer_75eacc89fb20_B51C_Contoso_University.png

사용자는 학생, 과목, 강사를 조회하고 업데이트 할 수 있습니다. 아래의 스크린 샷들은 여러분이 곧 만들 화면들입니다.


출처 : http://i1.asp.net/umbraco-beta-media/2577514/Windows-Live-Writer_75eacc89fb20_B51C_Students_Index_page.png


출처 : http://i1.asp.net/umbraco-beta-media/2577520/Windows-Live-Writer_75eacc89fb20_B51C_Students_Create_page.png


출처 : http://i1.asp.net/umbraco-beta-media/2577526/Windows-Live-Writer_75eacc89fb20_B51C_Instructors_index_page_4.png

이 사이트의 UI 스타일은 내장 템플릿들에 의해 만들어지는 것을 그대로 사용할 것입니다. 따라서, 이 컬럼에서는 어떻게 엔티티 프레임워크를 사용하는지에만 집중할 수 있을 것입니다.

엔티티 프레임워크 개발 방법

엔티티 프레임워크 내에서 데이터를 다루는 방법은 아래의 다이어그램에 나와 있는 것처럼 데이터베이스 우선, 모델 우선, 코드 우선의 세가지 방법이 있습니다.


출처 : http://i1.asp.net/umbraco-beta-media/2577532/Windows-Live-Writer_75eacc89fb20_B51C_Development_approaches_diagram_8c9f576c-ca82-4843-9177-c9fc84ea9bbb.png

데이터베이스 우선(Database First)

만약, 여러분이 데이터베이스를 이미 가지고 있다면 엔티티 프레임워크가 기존의 데이터베이스 객체(예: 테이블과 컬럼)에 대응되는 클래스와 속성으로 이루어진 데이터 모델을 자동으로 생성해 줍니다. 데이터베이스 구조(저장 스키마), 데이터 모델(개념적 모델) 그리고 이 두 모델 간 맵핑에 관한 정보들을 XML 구조로 된 .edmx 파일에 저장합니다. 비쥬얼 스튜디오는 .edmx 파일을 보여주고 편집할 수 있는 그래픽 방식의 엔티티 프레임워크 디자이너를 제공합니다. 웹 폼 컬럼 시리즈의 엔티티 프레임워크 시작하기 그리고 계속해서 엔티티 프레임워크 사용하기 섹션에서는 데이터베이스 우선 개발방법을 사용하고 있습니다.

모델 우선(Model First)

만약, 여러분이 아직 데이터베이스가 없다면 비쥬얼 스튜디오의 엔티티 프레임워크 디자이너를 사용하여 모델을 만들면서 시작하실 수 있습니다. 모델을 디자인한 후 디자이너에서 데이터베이스를 만들 수 있는 DDL(데이터 정의 언어)문을 생성하실 수 있습니다. 이 방법 또한 모델과 맵핑 정보를 저장하기 위해 .edmx 파일을 사용합니다. 엔티티 프레임워크 4의 새로운 점 컬럼은 모델 우선 개발방법을 간략히 설명하고 있습니다.

코드 우선(Code First)

여러분이 기존의 데이터베이스가 있든지 없든지 그와 무관하게 테이블과 컬럼에 해당하는 클래스와 속성을 코딩하고 .edmx 파일 없이 코딩한 클래스와 속성을 엔티티 프레임워크에서 사용하실 수 있습니다. 공식적인 이름은 코드 우선입니다만 때때로 코드 전용(Code only)이라고 불리기도 합니다. 개념적 모델과 저장 스키마 사이의 맵핑에 해당하는 여러분이 만든 클래스와 속성은 컨벤션(convention)과 특별한 맵핑 API에 의해 다뤄지게 됩니다. 만약 여러분이 데이터베이스를 아직 가지고 있지 않다면 엔티티 프레임워크가 여러분을 위해 데이터베이스를 자동으로 생성하거나 모델이 변경된 경우 데이터베이스를 제거(Drop)한 후 재생성 해줄 것입니다. 이 컬럼 시리즈에서는 코드 우선 개발방법을 사용할 것입니다.

코드 우선을 위해 개발된 데이터 접근 API는 DbContext 클래스를 기반으로 하고 있습니다. 이 API는 또한 데이터베이스 우선 방식과 모델 우선 워크플로우에서도 사용됩니다. 더 자세한 정보가 필요하시면, 엔티티 프레임워크 팀 블로그의 언제 Code first을 사용하는 것이 좋을까요?를 참조하세요.

POCO (평범한 CLR 객체)

여러분이 데이터베이스 우선 방식 또는 모델 우선 개발 방식을 사용할 때, 여러분의 데이터 모델 안에 있는 엔티티 클래스들은 기본으로 EntityObject로부터 상속받은 엔티티 프레임워크의 기능을 제공 받게 됩니다. 이는 이러한 클래스들이 기술적으로 지속성 무시(persistence ignorant) 객체가 아니며 그렇기에 도메인 지향 디자인의 요구 사항 중 하나를 만족할 수 없다는 의미가 됩니다. 엔티티 프레임워크의 모든 개발 방법에는 POCO(plain old CLR objects) 클래스도 사용할 수 있습니다. POCO 클래스를 사용하게 되면, EntityObject 클래스를 상속받지 않기 때문에 지속성 무시 객체(persistence-ignorant )가 됩니다. 이 컬럼에서는 POCO 클래스를 사용할 것입니다.

MVC 웹 응용 프로그램 만들기

시작하기 전에 여러분의 컴퓨터에 아래 목록이 프로그램을 설치되어 있는지 확인하십시오:

비주얼 스튜디오를 열고 ASP.NET MVC 3 Web Application 템플릿을 사용해서 "ContosoUniversity"라는 새 프로젝트를 생성합니다:


출처 : http://i1.asp.net/umbraco-beta-media/2577538/Windows-Live-Writer_75eacc89fb20_B51C_New_project_dialog_box_ff18ebb9-6aa9-4afd-93e9-af15d5b774b0.png

New ASP.NET MVC 3 Project 다이얼로그 박스에서 Internet Application 템플릿과 Razor 뷰 엔진을 선택하고 Create a unit test project 체크박스를 해제한 후 OK 버튼을 누릅니다.


출처 : http://i1.asp.net/umbraco-beta-media/2577544/Windows-Live-Writer_75eacc89fb20_B51C_Project_template_options_667f6b0d-8e57-42b9-acc9-11e77a9c9ade.png

사이트 스타일 설정하기

간단한 몇 가지 변경을 통해 사이트 메뉴, 레이아웃, 첫 화면을 설정할 것입니다.

Contoso 대학 메뉴를 설정하기 위해 Views\Shared\_Layout.cshtml 파일의 기존의 h1 헤딩 텍스트와 메뉴 링크들을 아래의 예제와 같이 바꿉니다.

<!DOCTYPE html>
<html>
<head>
  <title>@ViewBag.Title</title>
  <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
  <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
</head>
<body>
  <div class="page">
    <div id="header">
      <div id="title">
        <h1>Contoso University</h1>
      </div>

      <div id="logindisplay">
        @Html.Partial("_LogOnPartial")
      </div>
      <div id="menucontainer">
        <ul id="menu">
          <li>@Html.ActionLink("Home", "Index", "Home")</li>
          <li>@Html.ActionLink("About", "About", "Home")</li>
          <li>@Html.ActionLink("Students", "Index", "Student")</li>
          <li>@Html.ActionLink("Courses", "Index", "Course")</li>
          <li>@Html.ActionLink("Instructors", "Index", "Instructor")</li>
          <li>@Html.ActionLink("Departments", "Index", "Department")</li>
        </ul>
      </div>
    </div>
    <div id="main">
      @RenderBody()
    </div>
    <div id="footer">
    </div>
  </div>
</body>
</html>

Views\Home\Index.cshtml 파일에서 h2 헤딩 아래의 모든 내용을 지웁니다.

Controllers\HomeController.cs 파일에서 "Welcome to ASP.NET MVC!"를 "Welcome to Contoso University!"로 변경합니다.

Content\Site.css 파일에서 메뉴 탭을 왼쪽으로 이동시키기 위해 아래의 사항을 변경합니다.

  • #main 안에 아래의 예제처럼 clear: both;를 추가합니다.

      #main
    {
        clear: both;
        padding: 30px 30px 15px 30px;
        background-color: #fff;
        border-radius: 4px 0 0 0;
        -webkit-border-radius: 4px 0 0 0;
        -moz-border-radius: 4px 0 0 0;
    }
  • nav, #menucontainer 안에 아래의 예체처럼 clear: both; float: left; 를 추가합니다.

    nav,  
    #menucontainer {
        margin-top: 40px;
        clear: both;
        float: left;
    }

사이트를 실행하면 메인 메뉴와 첫 화면을 만나실 수 있습니다.


출처 : http://i1.asp.net/umbraco-beta-media/2577508/Windows-Live-Writer_75eacc89fb20_B51C_Contoso_University.png

데이터 모델 만들기

이제 여러분은 Contoso 대학 응용 프로그램을 위해 첫 엔티티 클래스를 만들 것입니다. 여러분은 아래 3개의 엔티티부터 시작할 것입니다.


출처 : http://i1.asp.net/umbraco-beta-media/2577556/Windows-Live-Writer_75eacc89fb20_B51C_Class_diagram.png

Student 엔티티와 Enrollment 엔티티는 일대다 관계이고, Course 엔티티와 Enrollment 엔티티 또한 일대다 관계입니다. 다른 말로 표현하면, 한 명의 학생은 여러 과목에 등록할 수 있고, 한 과목에 여러 명의 학생이 등록할 수 있다는 의미입니다.

아래의 섹션에서는 이 엔티티 별로 각각 한 개의 클래스를 생성할 것입니다.

주의 : 만약 여러분이 이 엔티티 클래스들을 생성하는 것을 끝마치기 전에 컴파일을 시도한다면 컴파일 에러를 만나게 될 것입니다.

Student 엔티티


출처 : http://i1.asp.net/umbraco-beta-media/2577562/Windows-Live-Writer_75eacc89fb20_B51C_Student_entity_d3e525a4-b62b-4257-8cf8-7170fb57dd34.png

Models 폴더 안에 Student.cs 파일을 생성하고 아래와 같이 변경합니다.

using System;
using System.Collections.Generic;

namespace ContosoUniversity.Models
{
    public class Student
    {
        public int StudentID { get; set; }
        public string LastName { get; set; }
        public string FirstMidName { get; set; }
        public DateTime EnrollmentDate { get; set; }
        public virtual ICollection<Enrollment> Enrollments { get; set; }
    }
}

StudentID 속성은 이 클래스에 대응되는 데이터베이스 테이블의 기본키 컬럼이 될 것입니다. 기본적으로 엔티티 프레임워크는 ID 또는 [클래스명ID]로 이름 붙은 속성을 기본키로 변환합니다.

Enrollments 속성은 탐색 속성입니다. 탐색속성은 이 엔티티에 연관된 다른 엔티티들을 담고 있습니다. 이 예제의 Student 엔티티의 Enrollments 속성은 Student 엔티티에 연관된 Enrollment 엔티티들을 담고 있습니다. 다른 말로 표현하면 만약 데이터베이스의 한 Student 행이 (Student의 기본키 값을 StudentID 외래키 컬럼에 보관하고 있는) 두 개의 Enrollment 행을 가지고 있다면 Student 엔티티의 Enrollments 탐색 속성은 두 개의 Enrollment 엔티티를 담고 있을 것입니다.

탐색 속성은 일반적으로 virtual로 정의하여 지연로드(lazy loading)라고 불리는 엔티티 프레임워크 함수의 장점을 가질 수 있습니다(지연 로딩에 대해서는 차후에 관계 데이터 읽어오기 컬럼에서 설명할 것입니다). 만약, 탐색 속성이 (다대다 관계 또는 일대다 관계로써) 다수의 엔티티를 담고 있다면 탐색속성의 타입은 반드시 ICollection으로 설정하여야 합니다.

Enrollment 엔티티


출처 : http://i1.asp.net/umbraco-beta-media/2577568/Windows-Live-Writer_75eacc89fb20_B51C_Enrollment_entity_140a15e0-c2f5-4bbd-a7a3-ca7b2f7622d5.png

Models 폴더안에 Enrollment.cs 파일을 생성하고 아래와 같이 변경합니다.

using System;
using System.Collections.Generic;

namespace ContosoUniversity.Models
{
    public class Enrollment
    {
        public int EnrollmentID { get; set; }
        public int CourseID { get; set; }
        public int StudentID { get; set; }
        public decimal? Grade { get; set; }
        public virtual Course Course { get; set; }
        public virtual Student Student { get; set; }
    }
}

decimal 타입 선언 다음의 물음표는 Grade 속성이 nullable임을 의미합니다. Grade 속성 값이 null일 경우와 0일 경우는 다릅니다. Null인 경우 아직 Grade 속성에 값이 할당되지 않은 것이고 0일 경우는 Grade 속성 값에 0이 할당된 것입니다.

StudentID 속성은 외래키이고 이에 일치되는 탐색속성은 Student입니다. 전에 본 Student.Enrollments 탐색 속성이 다수의 Enrollment 엔티티들을 담을 수 있었던 것과는 다르게 Enrollment 엔티티는 하나의 Student 엔티티와 결합하고 그래서 Student 속성은 오직 한 개의 Student 엔티티를 담을 수 있습니다.

CourseID 속성은 외래키이고 일치되는 탐색 속성은 Course 입니다. Enrollment 엔티티는 하나의 Course 엔티티와도 연관되어 있습니다.

Course 엔티티


출처 : http://i1.asp.net/umbraco-beta-media/2577574/Windows-Live-Writer_75eacc89fb20_B51C_Course_entity_1659670a-0ec1-4c03-964d-29c532525580.png

Models 폴더 안에 Course.cs 파일을 생성하고 아래와 같이 변경합니다.

using System;
using System.Collections.Generic;

namespace ContosoUniversity.Models
{
    public class Course
    {
        public int CourseID { get; set; }
        public string Title { get; set; }
        public int Credits { get; set; }
        public virtual ICollection<Enrollment> Enrollments { get; set; }
    }
}

Enrollments 속성은 탐색 속성입니다. Course 엔티티는 다수의 Enrollment 엔티티와 연관될 수 있습니다.

데이터베이스 컨텍스트 만들기

주어진 데이터 모델에 엔티티 프레임워크의 기능을 결합시켜 주는 메인 클래스는 데이터베이스 컨텍스트 클래스 입니다. 여러분은 이 클래스를 System.Data.Entity.DbContext를 상속하여 만들 수 있습니다. 코드에 여러분은 어떤 엔티티들을 데이터 모델안에 포함시킬 것인지 명시하여야 합니다. 여러분은 또한 엔티티 프레임워크의 특정 동작을 사용자 정의할 수 있습니다. 프로젝트를 위해 SchoolContext라는 클래스를 만듭니다.

우선 DAL이라는 폴더를 만듭니다. 그리고, 이 폴더 안에 SchoolContext.cs 파일을 생성하고 아래와 같이 코드를 변경합니다.

using System;
using System.Collections.Generic;
using System.Data.Entity;
using ContosoUniversity.Models;
using System.Data.Entity.ModelConfiguration.Conventions;

namespace ContosoUniversity.Models
{
    public class SchoolContext : DbContext
    {
        public DbSet<Student> Students { get; set; }
        public DbSet<Enrollment> Enrollments { get; set; }
        public DbSet<Course> Courses { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        }
    }
}

각각의 엔티티 집합(entity set)에 대해 DbSet 속성을 생성합니다. 엔티티 프레임워크에서의 엔티티 집합은 일반적으로 데이터베이스 테이블 해당하고, 엔티티는 테이블의 행(row)에 해당 합니다.

OnModelCreating 메소드의 코드는 테이블 명을 복수형으로 생성하는 것을 방지해 줍니다. 만약 여러분이 이렇게 설정하지 않는다면 생성되는 테이블 명은 Student, Course, Enrollment가 아닌 Students, Courses, Enrollments로 생성될 것입니다. 개발자들이 테이블 명이 복수형이여야 한다는 것에 동의하던지 말던지(개발자들 사이에서 테이블 명을 복수형으로 사용해야 한다는 의견에 논란이 있습니다만) 이 컬럼에서는 단수형을 사용할 것입니다. 어쨋든 중요한 점은 여러분이 선호하는 방식을 선택할 수 있고 이를 위해 이 코드를 포함하거나 또는 생략해야 한다는 것입니다.

(이러한 클래스들은 모두 Models 네임스페이스에 속해 있습니다. 이는 간혹 코드 우선방식이 엔티티 클래스들과 컨텍스트 클래스가 같은 네임스페이스 속해 있다고 가정하기 때문입니다)

연결 문자열(Connection String) 설정하기

연결문자열은 사실 직접 만들 필요가 없습니다. 만약, 여러분이 연결 문자열을 생성하지 않았다면 엔티티 프레임워크가 자동적으로 SQL Server Express 데이터베이스를 생성해 줄 것이기 때문입니다. 하지만 이 컬럼에서는 SQL Server Compact로 작업할 것이기에 연결문자열을 명시해줄 필요가 있습니다.

프로젝트의 Web.config 파일을 열고 새로운 연결 문자열을 connectionStrings 컬렉션에 아래와 같이 추가합니다(프로젝트의 루트 폴더에 있는 Web.config 파일에 아래의 코드를 추가하셔야 합니다. Views 폴더에 또 다른 Web.config 파일이 있지만 이 파일에는 아래의 코드를 추가하실 필요가 없습니다).

<add name="SchoolContext" connectionString="Data Source=|DataDirectory|School.sdf"
       providerName="System.Data.SqlServerCe.4.0"/>

자동으로 엔티티 프레임워크는 개체 컨텍스트명과 같은 연결 문자열을 찾습니다. 여러분이 추가한 이 연결 문자열은 App_Data 폴더에 School.sdf라는 이름의 SQL Server Compact 데이터베이스를 사용하도록 설정합니다.

테스트 데이터와 함께 데이터베이스 초기화하기

엔티티 프레임워크는 자동으로 여러분을 위해 응용 프로그램을 실행할 때 데이터베이스를 생성, 삭제 또는 재생성 할 수 있습니다. 여러분은 데이터베이스 생성, 삭제 또는 재생성이 일어나는 시기를 매번 응용프로그램을 실행할 때로 할 것인지 또는 데이터베이스의 모델이 변경된 경우에 할 것인지를 명시할 수 있습니다. 또한, 여러분은 테스트 데이터와 함께 데이터베이스를 생성하기 위해 엔티티 프레임워크가 데이터베이스를 생성 후 자동으로 호출하는 메소드를 포함하는 클래스를 작성하실 수 있습니다. 이 섹션에서 여러분은 모델이 변경된 경우 데이터베이스를 제거(Drop)하고 재생성하도록 설정할 것입니다.

DAL 폴더에 SchoolInitializer.cs 라는 이름의 새로운 클래스 파일을 생성하고 아래와 같이 데이터베이스를 생성 후 테스트 데이터를 로드하는 코드를 추가 합니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using ContosoUniversity.Models;

namespace ContosoUniversity.DAL
{
  public class SchoolInitializer : DropCreateDatabaseIfModelChanges<SchoolContext>
  {
    protected override void Seed(SchoolContext context)
    {
      var students = new List<Student>
      {
        new Student { FirstMidName = "Carson",  ?LastName = "Alexander", EnrollmentDate = DateTime.Parse("2005-09-01") },
        new Student { FirstMidName = "Meredith", LastName = "Alonso",  EnrollmentDate = DateTime.Parse("2002-09-01") },
        new Student { FirstMidName = "Arturo",  ?LastName = "Anand",  ?EnrollmentDate = DateTime.Parse("2003-09-01") },
        new Student { FirstMidName = "Gytis",  LastName = "Barzdukas", EnrollmentDate = DateTime.Parse("2002-09-01") },
        new Student { FirstMidName = "Yan",    LastName = "Li",    EnrollmentDate = DateTime.Parse("2002-09-01") },
        new Student { FirstMidName = "Peggy",  LastName = "Justice",  ?EnrollmentDate = DateTime.Parse("2001-09-01") },
        new Student { FirstMidName = "Laura",  LastName = "Norman",  EnrollmentDate = DateTime.Parse("2003-09-01") },
        new Student { FirstMidName = "Nino",  ?LastName = "Olivetto",  EnrollmentDate = DateTime.Parse("2005-09-01") }
      };
      students.ForEach(s => context.Students.Add(s));
      context.SaveChanges();

      var courses = new List<Course>
      {
        new Course { Title = "Chemistry",    Credits = 3, },
        new Course { Title = "Microeconomics", Credits = 3, },
        new Course { Title = "Macroeconomics", Credits = 3, },
        new Course { Title = "Calculus",    ?Credits = 4, },
        new Course { Title = "Trigonometry",  ?Credits = 4, },
        new Course { Title = "Composition",  Credits = 3, },
        new Course { Title = "Literature",  ?Credits = 4, }
      };
      courses.ForEach(s => context.Courses.Add(s));
      context.SaveChanges();

      var enrollments = new List<Enrollment>
      {
        new Enrollment { StudentID = 1, CourseID = 1, Grade = 1 },
        new Enrollment { StudentID = 1, CourseID = 2, Grade = 3 },
        new Enrollment { StudentID = 1, CourseID = 3, Grade = 1 },
        new Enrollment { StudentID = 2, CourseID = 4, Grade = 2 },
        new Enrollment { StudentID = 2, CourseID = 5, Grade = 4 },
        new Enrollment { StudentID = 2, CourseID = 6, Grade = 4 },
        new Enrollment { StudentID = 3, CourseID = 1      },
        new Enrollment { StudentID = 4, CourseID = 1,      ?},
        new Enrollment { StudentID = 4, CourseID = 2, Grade = 4 },
        new Enrollment { StudentID = 5, CourseID = 3, Grade = 3 },
        new Enrollment { StudentID = 6, CourseID = 4      },
        new Enrollment { StudentID = 7, CourseID = 5, Grade = 2 },
      };
      enrollments.ForEach(s => context.Enrollments.Add(s));
      context.SaveChanges();
    }
  }
}

Seed 메소드는 데이터베이스 컨텍스트 개체를 파라미터로 넘겨받고 Seed 메소드 안에서 데이터베이스 컨텍스트 개체를 사용하여 데이터베이스에 새로운 엔티티들을 추가합니다. 각각의 엔티티 타입별로 새로운 엔티티들의 컬렉션을 만들어 각각의 엔티티에 맞는 DbSet 속성에 엔티티들를 추가하고 변경사항을 데이터베이스에 저장합니다. 각각의 그룹 엔티티(students, courses, enrollments)에 엔티티들를 추가한 후 매번 SaveChanges 메소드를 호출해야 할 필요는 없습니만, 여기서 매번 호출하는 이유는 데이터베이스에 데이터를 기록하는 중에 에러가 발생하는 경우 여러분이 문제가 발생하는 코드를 쉽게 찾을 수 있도록 하기 위함입니다.

이니셜라이져가 응용 프로그램이 시작할 때 실행될 수 있도록 Global.asax.cs 파일을 다음과 같이 변경합니다.

  • using문을 추가합니다.

    using System.Data.Entity;
    using ContosoUniversity.Models;
    using ContosoUniversity.DAL;
  • Application_Start 메소드에서 데이터베이스 이니셜라이져 코드를 실행하는 엔티티 프레임워크의 메소드를 호출합니다.

    Database.SetInitializer<SchoolContext>(new SchoolInitializer());

이제 응용 프로그램이 설정되었습니다. 여러분이 응용 프로그램을 시작하여 데이터베이스에 처음 엑세스 할 때, 엔티티 프레임워크는 데이터베이스와 모델(SchoolContext 클래스)를 비교하여 변경사항이 있을 경우 데이터베이스를 제거(Drop)하고 재성성할 것입니다.

주의 : 운영(production) 웹 서버로 배포할 경우에는 데이터베이스에 테스트 데이터를 생성하는 코드(seed)를 제거해야 합니다.

이제 데이터를 보여주는 웹 페이지를 만들고, 데이터를 요청하여 자동으로 데이터베이스를 생성할 것입니다. 이를 위해 새로운 컨트롤러를 만들어 봅시다. 하지만 그전에 [MVC 컨트롤러 스케폴딩]이 가능한 모델과 컨텍스트 클래스를 만들기 위해 프로젝트를 빌드합니다.

Student 컨트롤러 생성하기

Student 컨트롤러를 생성하기 위해 [솔루션 탐색기]에서 Controllers 폴더를 마우스 오른쪽 버튼으로 클릭한 다음 Add > Controllers 메뉴를 선택합니다. Add Controller 다이얼로그 상자가 나타나면 아래와 같이 설정하고 Add 버튼을 클릭합니다.

  • Controller 이름 : StudentController.
  • Template : Controller with read/write actions and views, using Entity Framework. (기본 값)
  • Model 클래스 : Student (ContosoUniversity.Models). (만약, 드랍다운 목록에서 이 옵션을 찾을 수 없다면 프로젝트를 빌드한 후에 다시 시도 하십시오.)
  • Data context 클래스 : SchoolContext (ContosoUniversity.Models).
  • Views: Razor (CSHTML) (기본값)


출처 : http://i1.asp.net/umbraco-beta-media/2577580/Windows-Live-Writer_75eacc89fb20_B51C_Add_Controller_dialog_box_for_Student_controller_e8084aea-547c-491c-80f8-75816930098c.png

Controllers\StudentController.cs 파일을 열면 데이터베이스 컨텍스트 객체로 인스턴스화 되어 있는 클래스 변수를 보실 수 있습니다

private SchoolContext db = new SchoolContext();

Index 액션 메소드는 데이터베이스 컨택스트 인스턴스의 Students 속성으로부터 학생 리스트를 얻습니다.

public ViewResult Index()
{
    return View(db.Students.ToList());
}

자동 스캐폴딩은 또한 Student 뷰 집합을 생성합니다. 기본 헤딩과 Index 뷰의 컬럼 순서를 사용자 정의하기 위해 Views\Student\Index.cshtml 파일을 열고 아래와 같이 코드를 변경합니다.

@model IEnumerable<ContosoUniversity.Models.Student>

@{
  ViewBag.Title = "Students";
}

<h2>Students</h2>

<p>
  @Html.ActionLink("Create New", "Create")
</p>
<table>
  <tr>
    <th></th>
    <th>Last Name</th>
    <th>First Name</th>
    <th>Enrollment Date</th>
  </tr>

@foreach (var item in Model) {
  <tr>
    <td>
      @Html.ActionLink("Edit", "Edit", new { id=item.StudentID }) |
      @Html.ActionLink("Details", "Details", new { id=item.StudentID }) |
      @Html.ActionLink("Delete", "Delete", new { id=item.StudentID })
    </td>
    <td>
      @Html.DisplayFor(modelItem => item.LastName)
    </td>
    <td>
      @Html.DisplayFor(modelItem => item.FirstMidName)
    </td>
    <td>
      @Html.DisplayFor(modelItem => item.EnrollmentDate)
    </td>
  </tr>
}
</table>

사이트를 실행하여 Students 탭을 클릭하면 학생 리스트를 볼 수 있습니다.


출처 : http://i1.asp.net/umbraco-beta-media/2577586/Windows-Live-Writer_75eacc89fb20_B51C_Students_Index_page_2b429096-c89f-4c08-ad16-e42c1a5abd74.png

브라우저를 닫고 [솔루션 탐색기]에서 ContosoUniversity 프로젝트를 선택합니다(솔루션이 아닌 프로젝트를 선택해야 합니다). 만약 Show all Files 모드가 아니라면 Show all Files 를 클릭합니다. Refresh 버튼을 클릭하고 App_Data 폴더를 펼쳐 School.sdf 파일이 있는지 확인합니다.


출처 : http://i1.asp.net/umbraco-beta-media/2577592/Windows-Live-Writer_75eacc89fb20_B51C_School.sdf_file_in_Solution_Explorer_30905de5-b269-4bb0-8497-686a1260dc24.png

School.sdf 를 더블클릭하여 Server Explorer를 열고 Tables 폴더를 펼쳐 데이터베이스에 생성된 테이블들을 확인합니다.

주의 : 만약 School.sdf를 더블클릭할 때 에러가 난다면 Visual Studio 2010 SP1 Tools for SQL Server Compact 4.0가 설치되어 있는지 확인합니다 (이 페이지 상단에 있는 준비사항 목록의 소프트웨어 링크를 확인 하세요). 만약 설치되어 있다면 비쥬얼 스튜디오를 종료 후 다시 실행합니다.


출처 : http://i1.asp.net/umbraco-beta-media/2577598/Windows-Live-Writer_75eacc89fb20_B51C_Server_Explorer_showing_School_tables.png

각각의 엔티티 집합별로 하나의 테이블이 존재하고, 거기에 추가적으로 하나의 테이블이 더 있을 것입니다. EdmMetadata 테이블은 엔티티 프레임워크에 의해 모델과 데이터베이스가 일치하지 않는 경우를 판단하기 위해 사용됩니다 SchoolInitializer 클래스에 의해 테이블에 로드된 데이터를 살펴보려면 테이블 중에 하나를 선택하고 마우스 오른쪽 버튼을 클릭한 뒤, Show Table Data 를 선택하면 됩니다.


출처 : http://i1.asp.net/umbraco-beta-media/2577604/Windows-Live-Writer_75eacc89fb20_B51C_Table_data_in_Student_table_bcec9222-b4ea-4934-8aab-3eeb820378d0.png

확인이 다 끝났다면 연결을 종료합니다(만약 연결을 종료하지 않는다면 다음 번 프로젝트 실행 시에 에러가 날 수 있습니다).


출처 : http://i1.asp.net/umbraco-beta-media/2577610/Windows-Live-Writer_75eacc89fb20_B51C_Close_the_SQL_Compact_connection_8d2562e2-1198-425e-b170-7ff21481fdd1.png

규약

엔티티 프레임워크가 자동으로 데이터베이스를 생성할 수 있게 하기 위해서 여러분이 작성해야 했던 코드량은 엔티티 프레임워크의 규약 또는 추정을 통해 최소화될 수 있습니다. 몇몇의 규약과 추정은 이미 앞에서 언급하였습니다만, 다시 정리하자면 다음과 같습니다.

  • 테이블 명처럼 엔티티 클래스 명에도 복수형이 사용된다.
  • 엔티티 속성 명은 컬럼 명으로 사용된다.
  • 엔티티 속성 명이 ID 혹은 클래스명ID이면 기본키로 인식된다.
  • 엔티티 프레임워크는 컨텍스트 클래스에 사용되는 이름과 똑같은 연결문자열을 찾아 데이터베이스를 연결한다

위의 규약들은 재정의될 수 있습니다(예를 들면, 테이블 명에 단수형을 사용하도록 명시할 수 있습니다). 여러분은 이 시리즈의 다음 튜터리얼인 더 복잡한 데이터 모델만들기에서 더 많은 규약들과 어떻게 그것들을 재정의하는 지에 대해 학습할 것입니다.

이제 엔티티 프레임워크와 SQL Server Compact를 사용하여 간단한 응용 프로그램을 완성하였습니다. 다음 컬럼에서는 기본적인 CRUD (create, read, update, delete) 기능을 수행하기 위해서는 어떻게 해야 하는지를 배울 것 입니다.

그 밖의 엔티티 프레임워크 관련 참고 문서들은 이 컬럼 시리즈의 마지막 컬럼의 끝 부분에서 찾으실 수 있습니다.


authored by


 
 
.NET과 Java 동영상 기반의 교육사이트

로딩 중입니다...

서버 프레임워크 지원 : NeoDEEX
based on ASP.NET 3.5
Creative Commons License
{5}
{2} 읽음   :{3} ({4})