자습서: MVC 5를 사용하여 Entity Framework 6 Code First 시작

참고

새로운 개발을 위해 ASP.NET MVC 컨트롤러 및 뷰를 통해 Razor Pages를 ASP.NET Core 것이 좋습니다. Razor Pages를 사용하는 자습서 시리즈와 유사한 자습서 시리즈는 자습서: ASP.NET Core Razor Pages 시작을 참조하세요. 새 자습서:

  • 자습서 내용을 좀 더 쉽게 진행할 수 있습니다.
  • 더 많은 EF Core 모범 사례를 제공합니다.
  • 더 효율적인 쿼리를 사용합니다.
  • 최신 API가 탑재되어 최신 상태입니다.
  • 더 많은 기능을 다룹니다.
  • 새 애플리케이션 개발을 위해 선호되는 방법입니다.

이 자습서 시리즈에서는 데이터 액세스를 위해 Entity Framework 6을 사용하는 ASP.NET MVC 5 애플리케이션을 빌드하는 방법을 알아봅니다. 이 자습서에서는 Code First 워크플로를 사용합니다. Code First, Database First 및 Model First 중에서 선택하는 방법에 대한 자세한 내용은 모델 만들기를 참조하세요.

이 자습서 시리즈에서는 Contoso University 샘플 애플리케이션을 빌드하는 방법을 설명합니다. 샘플 애플리케이션은 간단한 대학 웹 사이트입니다. 이를 통해 학생, 과정 및 강사 정보를 보고 업데이트할 수 있습니다. 만드는 두 화면은 다음과 같습니다.

Students_Index_page

학생 편집

이 자습서에서는 다음을 수행합니다.

  • MVC 웹앱 만들기
  • 사이트 스타일 설정
  • Entity Framework 6 설치
  • 데이터 모델 만들기
  • 데이터베이스 컨텍스트 만들기
  • 테스트 데이터로 DB 초기화
  • LocalDB를 사용하도록 EF 6 설정
  • 컨트롤러 및 뷰 만들기
  • 데이터베이스 보기

사전 요구 사항

MVC 웹앱 만들기

  1. Visual Studio를 열고 ASP.NET 웹 애플리케이션(.NET Framework) 템플릿을 사용하여 C# 웹 프로젝트를 만듭니다. 프로젝트 이름을 ContosoUniversity로 지정하고 확인을 선택합니다.

    Visual Studio의 새 프로젝트 대화 상자

  2. 새 ASP.NET 웹 애플리케이션 - ContosoUniversity에서 MVC를 선택합니다.

    Visual Studio의 새 웹앱 대화 상자

    참고

    기본적으로 인증 옵션은 인증없음으로 설정됩니다. 이 자습서에서는 웹앱에서 사용자가 로그인할 필요가 없습니다. 또한 로그인한 사용자에 따라 액세스를 제한하지 않습니다.

  3. 확인을 선택하여 프로젝트를 만듭니다.

사이트 스타일 설정

몇 가지 간단한 변경 내용으로 사이트 메뉴, 레이아웃 및 홈 페이지를 설정합니다.

  1. Views\Shared\_Layout.cshtml을 열고 다음을 변경합니다.

    • "내 ASP.NET 애플리케이션" 및 "애플리케이션 이름"의 각 항목을 "Contoso University"로 변경합니다.
    • 학생, 과정, 강사 및 부서에 대한 메뉴 항목을 추가하고 연락처 항목을 삭제합니다.

    변경 내용은 다음 코드 조각에서 강조 표시됩니다.

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>@ViewBag.Title - Contoso University</title>
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    </head>
    <body>
        <div class="navbar navbar-inverse navbar-fixed-top">
            <div class="navbar-inner">
                <div class="container">
                    <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    @Html.ActionLink("Contoso University", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
                    <div class="nav-collapse collapse">
                        <ul class="nav">
                            <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>
        </div>
    
        <div class="container">
            @RenderBody()
            <hr />
            <footer>
                <p>&copy; @DateTime.Now.Year - Contoso University</p>
            </footer>
        </div>
    
        @Scripts.Render("~/bundles/jquery")
        @Scripts.Render("~/bundles/bootstrap")
        @RenderSection("scripts", required: false)
    </body>
    </html>
    
  2. Views\Home\Index.cshtml에서 파일의 내용을 다음 코드로 바꿔 ASP.NET 및 MVC에 대한 텍스트를 이 애플리케이션에 대한 텍스트로 바꿉니다.

    @{
        ViewBag.Title = "Home Page";
    }
    
    <div class="jumbotron">
        <h1>Contoso University</h1>
    </div>
    <div class="row">
        <div class="col-md-4">
            <h2>Welcome to Contoso University</h2>
            <p>Contoso University is a sample application that
            demonstrates how to use Entity Framework 6 in an 
            ASP.NET MVC 5 web application.</p>
        </div>
        <div class="col-md-4">
            <h2>Build it from scratch</h2>
            <p>You can build the application by following the steps in the tutorial series on the ASP.NET site.</p>
            <p><a class="btn btn-default" href="http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/">See the tutorial &raquo;</a></p>
        </div>
        <div class="col-md-4">
            <h2>Download it</h2>
            <p>You can download the completed project.</p>
            <p><a class="btn btn-default" href="https://webpifeed.blob.core.windows.net/webpifeed/Partners/ASP.NET%20MVC%20Application%20Using%20Entity%20Framework%20Code%20First.zip">Download &raquo;</a></p>
        </div>
    </div>
    
  3. Ctrl+F5를 눌러 웹 사이트를 실행합니다. 기본 메뉴가 있는 홈페이지가 표시됩니다.

Entity Framework 6 설치

  1. 도구 메뉴에서 NuGet 패키지 관리자를 선택한 다음 패키지 관리자 콘솔을 선택합니다.

  2. 패키지 관리자 콘솔 창에서 다음 명령을 입력합니다.

    Install-Package EntityFramework
    

이 단계는 이 자습서에서 수동으로 수행하는 몇 가지 단계 중 하나이지만 ASP.NET MVC 스캐폴딩 기능을 통해 자동으로 수행되었을 수 있습니다. EF(Entity Framework)를 사용하는 데 필요한 단계를 볼 수 있도록 수동으로 수행합니다. 나중에 스캐폴딩을 사용하여 MVC 컨트롤러 및 뷰를 만듭니다. 다른 방법은 스캐폴딩이 EF NuGet 패키지를 자동으로 설치하고, 데이터베이스 컨텍스트 클래스를 만들고, 연결 문자열을 만들도록 하는 것입니다. 이러한 방식으로 수행할 준비가 되면 엔터티 클래스를 만든 후 해당 단계를 건너뛰고 MVC 컨트롤러를 스캐폴드하기만 하면 됩니다.

데이터 모델 만들기

다음으로 Contoso University 애플리케이션에 대한 엔터티 클래스를 만듭니다. 다음 세 가지 엔터티로 시작합니다.

과정<->등록<->학생

엔터티 관계
등록 과정 일대다
등록할 학생 일대다

StudentEnrollment 엔터티 간에 일대다 관계가 있으며 CourseEnrollment 엔터티 간에 일대다 관계가 있습니다. 즉, 학생은 개수에 관계 없이 강좌에 등록될 수 있으며 강좌는 등록된 학생이 여러 명일 수 있습니다.

다음 섹션에서는 이러한 엔터티 각각에 대한 클래스를 만듭니다.

참고

이러한 엔터티 클래스를 모두 만들기 전에 프로젝트를 컴파일하려고 하면 컴파일러 오류가 발생합니다.

학생 엔터티

  • Models 폴더에서 솔루션 탐색기 폴더를 마우스 오른쪽 단추로 클릭하고 클래스 추가>를 선택하여 Student.cs라는클래스 파일을 만듭니다. 템플릿 코드를 다음 코드로 바꿉니다.

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

ID 속성은 이 클래스에 해당하는 데이터베이스 테이블의 기본 키 열이 됩니다. 기본적으로 Entity Framework는 명명된 속성 또는 클래스ID 이름을 ID 기본 키로 해석합니다.

Enrollments 속성은 탐색 속성입니다. 탐색 속성은 이 엔터티와 관련된 다른 엔터티를 포함합니다. 이 경우 Enrollments 엔터티의 Student 속성은 해당 Student 엔터티와 관련된 모든 Enrollment 엔터티를 보유합니다. 즉, 데이터베이스의 지정된 Student 행에 두 개의 관련 Enrollment 행(외래 키 열에 해당 학생의 기본 키 값이 포함된 행)이 있는 StudentID 경우 해당 Student 엔터티의 Enrollments 탐색 속성에는 이러한 두 Enrollment 엔터티가 포함됩니다.

탐색 속성은 일반적으로 로 정의 virtual 되므로 지연 로드와 같은 특정 Entity Framework 기능을 활용할 수 있습니다. 지연 로드는 이 시리즈의 뒷부분에 있는 읽기 관련 데이터 자습서에서 나중에 설명합니다.

탐색 속성이 여러 엔터티를 포함할 수 있는 경우(다대다 또는 일대다 관계로), 해당 형식은 ICollection와 같이 항목이 추가, 삭제 및 업데이트될 수 있는 목록이어야 합니다.

등록 엔터티

  • Models 폴더에서Enrollment.cs를 만들고 기존 코드를 다음 코드로 바꿉니다.

    namespace ContosoUniversity.Models
    {
        public enum Grade
        {
            A, B, C, D, F
        }
    
        public class Enrollment
        {
            public int EnrollmentID { get; set; }
            public int CourseID { get; set; }
            public int StudentID { get; set; }
            public Grade? Grade { get; set; }
            
            public virtual Course Course { get; set; }
            public virtual Student Student { get; set; }
        }
    }
    

속성이 EnrollmentID 기본 키가 됩니다. 이 엔터티는 엔터티에서 본 Student 것처럼 클래스 이름ID 패턴을 자체적인 대신 ID 사용합니다. 일반적으로 하나의 패턴을 선택하고 이를 데이터 모델 전체에서 사용합니다. 여기에서 변형은 패턴 중 하나를 사용할 수 있음을 보여 줍니다. 이후 자습서에서는 를 사용하지 않고 classname 를 사용하면 ID 데이터 모델에서 상속을 더 쉽게 구현하는 방법을 확인할 수 있습니다.

속성은 Grade열거형입니다. Grade 형식 선언 뒤에 있는 물음표는 Grade 속성이 nullable이라는 것을 나타냅니다. null인 성적은 0등급과 다릅니다. null은 성적이 알려지지 않았거나 아직 할당되지 않았음을 의미합니다.

StudentID 속성은 외래 키로, 해당 탐색 속성은 Student입니다. Enrollment 엔터티는 하나의 Student 엔터티와 연결되어 있으므로 속성은 단일 Student 엔터티만 포함할 수 있습니다(이전에 살펴본 여러 Enrollment 엔터티를 포함할 수 있는 Student.Enrollments 탐색 속성과 달리).

CourseID 속성은 외래 키로, 해당 탐색 속성은 Course입니다. Enrollment 엔터티는 하나의 Course 엔터티와 연결됩니다.

Entity Framework는 속성을 탐색 속성 이름 기본 키 속성 이름><>인 경우< 외래 키 속성으로 해석합니다(예 StudentIDStudent: 엔터티의 기본 키가 이므로 ID탐색 속성 Student 의 경우). 외래 키 속성의 이름은 단순히 <기본 키 속성 이름과> 같을 수도 있습니다(예: CourseIDCourse 엔터티의 기본 키는 CourseID).

강좌 엔터티

  • Models 폴더에서 Course.cs를 만들고 템플릿 코드를 다음 코드로 바꿉니다.

    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace ContosoUniversity.Models
    {
        public class Course
        {
            [DatabaseGenerated(DatabaseGeneratedOption.None)]
            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 엔터티의 개수와 관련이 있을 수 있습니다.

이 시리즈의 이후의 자습서에서 DatabaseGeneratedAttribute 특성에 대해 자세히 설명합니다. 기본적으로 이 특성을 통해 생성하는 데이터베이스를 갖는 대신 강좌에 대한 기본 키를 입력할 수 있습니다.

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

지정된 데이터 모델에 대한 Entity Framework 기능을 조정하는 기본 클래스는 데이터베이스 컨텍스트 클래스입니다. System.Data.Entity.DbContext 클래스에서 파생하여 이 클래스를 만듭니다. 코드에서 데이터 모델에 포함되는 엔터티를 지정합니다. 특정 Entity Framework 동작을 사용자 지정할 수도 있습니다. 이 프로젝트에서 클래스 이름은 SchoolContext로 지정됩니다.

  • ContosoUniversity 프로젝트에서 폴더를 만들려면 솔루션 탐색기 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가를 클릭한 다음 새 폴더를 클릭합니다. 새 폴더의 이름을 DAL (데이터 액세스 계층의 경우)으로 지정합니다. 해당 폴더에서 SchoolContext.cs라는 새 클래스 파일을 만들고 템플릿 코드를 다음 코드로 바꿉니다.

    using ContosoUniversity.Models;
    using System.Data.Entity;
    using System.Data.Entity.ModelConfiguration.Conventions;
    
    namespace ContosoUniversity.DAL
    {
        public class SchoolContext : DbContext
        {
        
            public SchoolContext() : base("SchoolContext")
            {
            }
            
            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>();
            }
        }
    }
    

엔터티 집합 지정

이 코드는 각 엔터티 집합에 대한 DbSet 속성을 만듭니다. Entity Framework 용어에서 엔터티 집합 은 일반적으로 데이터베이스 테이블에 해당하며 엔터티는 테이블의 행에 해당합니다.

참고

DbSet<Course> 문을 생략 DbSet<Enrollment> 할 수 있으며 동일하게 작동합니다. 엔터티가 엔터티를 참조하고 엔터티가 엔터티를 Enrollment 참조 Course 하기 때문에 Student Entity Framework는 Enrollment 이러한 엔터티를 암시적으로 포함합니다.

연결 문자열 지정

나중에 Web.config 파일에 추가할 연결 문자열의 이름이 생성자에 전달됩니다.

public SchoolContext() : base("SchoolContext")
{
}

Web.config 파일에 저장된 이름 대신 연결 문자열 자체를 전달할 수도 있습니다. 사용할 데이터베이스를 지정하는 옵션에 대한 자세한 내용은 연결 문자열 및 모델을 참조하세요.

연결 문자열이나 이름을 명시적으로 지정하지 않으면 Entity Framework는 연결 문자열 이름이 클래스 이름과 동일하다고 가정합니다. 이 예제 SchoolContext의 기본 연결 문자열 이름은 명시적으로 지정하는 것과 동일한 입니다.

단수 테이블 이름 지정

OnModelCreating 메서드의 문은 modelBuilder.Conventions.Remove 테이블 이름이 복수화되지 않도록 방지합니다. 이 작업을 수행하지 않은 경우 데이터베이스에서 생성된 테이블의 이름은 Students, CoursesEnrollments입니다. 대신 테이블 이름은 , CourseEnrollment입니다Student. 개발자는 테이블 이름을 복수화할지 여부에 대해 동의하지 않습니다. 이 자습서에서는 단수 형식을 사용하지만 중요한 점은 이 코드 줄을 포함하거나 생략하여 원하는 양식을 선택할 수 있다는 것입니다.

테스트 데이터로 DB 초기화

Entity Framework는 애플리케이션이 실행되면 자동으로 데이터베이스를 만들거나 삭제하고 다시 만들 수 있습니다. 애플리케이션이 실행될 때마다 또는 모델이 기존 데이터베이스와 동기화되지 않은 경우에만 수행되도록 지정할 수 있습니다. 데이터베이스를 Seed 만든 후 Entity Framework에서 자동으로 호출하는 메서드를 작성하여 테스트 데이터로 채울 수도 있습니다.

기본 동작은 데이터베이스가 없는 경우에만 데이터베이스를 만들고 모델이 변경되고 데이터베이스가 이미 있는 경우 예외를 throw하는 것입니다. 이 섹션에서는 모델이 변경될 때마다 데이터베이스를 삭제하고 다시 만들어야 한다고 지정합니다. 데이터베이스를 삭제하면 모든 데이터가 손실됩니다. 데이터베이스를 다시 만들고 테스트 데이터를 다시 만들 때 메서드가 실행되므로 일반적으로 개발 Seed 중에는 괜찮습니다. 그러나 프로덕션 환경에서는 일반적으로 데이터베이스 스키마를 변경해야 할 때마다 모든 데이터가 손실되는 것을 원하지 않습니다. 나중에 데이터베이스를 삭제하고 다시 만드는 대신 Code First 마이그레이션 사용하여 데이터베이스 스키마를 변경하여 모델 변경을 처리하는 방법을 알아보세요.

  1. 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 : System.Data.Entity. 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{CourseID=1050,Title="Chemistry",Credits=3,},
                new Course{CourseID=4022,Title="Microeconomics",Credits=3,},
                new Course{CourseID=4041,Title="Macroeconomics",Credits=3,},
                new Course{CourseID=1045,Title="Calculus",Credits=4,},
                new Course{CourseID=3141,Title="Trigonometry",Credits=4,},
                new Course{CourseID=2021,Title="Composition",Credits=3,},
                new Course{CourseID=2042,Title="Literature",Credits=4,}
                };
                courses.ForEach(s => context.Courses.Add(s));
                context.SaveChanges();
                var enrollments = new List<Enrollment>
                {
                new Enrollment{StudentID=1,CourseID=1050,Grade=Grade.A},
                new Enrollment{StudentID=1,CourseID=4022,Grade=Grade.C},
                new Enrollment{StudentID=1,CourseID=4041,Grade=Grade.B},
                new Enrollment{StudentID=2,CourseID=1045,Grade=Grade.B},
                new Enrollment{StudentID=2,CourseID=3141,Grade=Grade.F},
                new Enrollment{StudentID=2,CourseID=2021,Grade=Grade.F},
                new Enrollment{StudentID=3,CourseID=1050},
                new Enrollment{StudentID=4,CourseID=1050,},
                new Enrollment{StudentID=4,CourseID=4022,Grade=Grade.F},
                new Enrollment{StudentID=5,CourseID=4041,Grade=Grade.C},
                new Enrollment{StudentID=6,CourseID=1045},
                new Enrollment{StudentID=7,CourseID=3141,Grade=Grade.A},
                };
                enrollments.ForEach(s => context.Enrollments.Add(s));
                context.SaveChanges();
            }
        }
    }
    

    메서드는 Seed 데이터베이스 컨텍스트 개체를 입력 매개 변수로 사용하고 메서드의 코드는 해당 개체를 사용하여 데이터베이스에 새 엔터티를 추가합니다. 각 엔터티 형식에 대해 코드는 새 엔터티의 컬렉션을 만들고 적절한 DbSet 속성에 추가한 다음 변경 내용을 데이터베이스에 저장합니다. 여기에서 수행한 것처럼 각 엔터티 그룹 다음에 메서드를 호출 SaveChanges 할 필요는 없지만 코드가 데이터베이스에 쓰는 동안 예외가 발생하는 경우 문제의 원인을 찾는 데 도움이 됩니다.

  2. Entity Framework에 이니셜라이저 클래스를 사용하도록 지시하려면 다음 예제와 같이 애플리케이션 Web.config 파일(루트 프로젝트 폴더에 있는 요소)의 요소에 요소를 entityFramework 추가합니다.

    <entityFramework>
      <contexts>
        <context type="ContosoUniversity.DAL.SchoolContext, ContosoUniversity">
          <databaseInitializer type="ContosoUniversity.DAL.SchoolInitializer, ContosoUniversity" />
        </context>
      </contexts>
      <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
        <parameters>
          <parameter value="v11.0" />
        </parameters>
      </defaultConnectionFactory>
      <providers>
        <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      </providers>
    </entityFramework>
    

    context type 정규화된 컨텍스트 클래스 이름과 해당 클래스의 어셈블리를 지정하고 databaseinitializer type 이니셜라이저 클래스의 정규화된 이름과 해당 클래스의 어셈블리를 지정합니다. (EF에서 이니셜라이저를 사용하지 않으려면 요소disableDatabaseInitialization="true"context 특성을 설정할 수 있습니다. .) 자세한 내용은 구성 파일 설정을 참조하세요.

    Web.config 파일에서 이니셜라이저를 설정하는 대신 Global.asax.cs 파일의 Application_Start 메서드에 문을 추가하여 Database.SetInitializer 코드에서 이 작업을 수행하는 것입니다. 자세한 내용은 Entity Framework Code First의 데이터베이스 이니셜라이저 이해를 참조하세요.

이제 애플리케이션의 지정된 실행에서 데이터베이스에 처음으로 액세스할 때 Entity Framework가 데이터베이스를 모델(및 SchoolContext 엔터티 클래스)과 비교하도록 애플리케이션이 설정되었습니다. 차이가 있는 경우 애플리케이션은 데이터베이스를 삭제하고 다시 만듭니다.

참고

프로덕션 웹 서버에 애플리케이션을 배포하는 경우 데이터베이스를 삭제하고 다시 만드는 코드를 제거하거나 사용하지 않도록 설정해야 합니다. 이 시리즈의 이후 자습서에서 이 작업을 수행합니다.

LocalDB를 사용하도록 EF 6 설정

LocalDB는 SQL Server Express 데이터베이스 엔진의 경량 버전입니다. 쉽게 설치 및 구성하고, 주문형으로 시작하고, 사용자 모드에서 실행됩니다. LocalDB는 데이터베이스를 .mdf 파일로 작업할 수 있는 SQL Server Express 특수 실행 모드에서 실행됩니다. 프로젝트와 함께 데이터베이스를 복사하려면 웹 프로젝트의 App_Data 폴더에 LocalDB 데이터베이스 파일을 배치할 수 있습니다. SQL Server Express 사용자 instance 기능을 사용하면 .mdf 파일로 작업할 수도 있지만 사용자 instance 기능은 더 이상 사용되지 않으므로 .mdf 파일 작업에 LocalDB를 사용하는 것이 좋습니다. LocalDB는 Visual Studio와 함께 기본적으로 설치됩니다.

일반적으로 SQL Server Express 프로덕션 웹 애플리케이션에 사용되지 않습니다. 특히 LocalDB는 IIS로 작동하도록 설계되지 않았기 때문에 웹 애플리케이션에서 프로덕션용으로 사용하지 않는 것이 좋습니다.

  • 이 자습서에서는 LocalDB를 사용합니다. 다음 예제와 같이 애플리케이션 Web.config 파일을 열고 요소 앞에 appSettings 요소를 추가 connectionStrings 합니다. (루트 프로젝트 폴더에서 Web.config 파일을 업데이트해야 합니다. Views 하위 폴더에는 업데이트할 필요가 없는 Web.config 파일도 있습니다.)

    <connectionStrings>
        <add name="SchoolContext" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=ContosoUniversity1;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/>
    </connectionStrings>
    <appSettings>
      <add key="webpages:Version" value="3.0.0.0" />
      <add key="webpages:Enabled" value="false" />
      <add key="ClientValidationEnabled" value="true" />
      <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    </appSettings>
    

추가한 연결 문자열은 Entity Framework가 ContosoUniversity1.mdf라는 LocalDB 데이터베이스를 사용하도록 지정합니다. (데이터베이스는 아직 없지만 EF는 데이터베이스를 만듭니다.) App_Data 폴더에 데이터베이스를 만들려면 연결 문자열에 를 추가할 AttachDBFilename=|DataDirectory|\ContosoUniversity1.mdf 수 있습니다. 연결 문자열에 대한 자세한 내용은 ASP.NET 웹 애플리케이션에 대한 연결 문자열 SQL Server 참조하세요.

실제로 Web.config 파일에 연결 문자열이 필요하지 않습니다. 연결 문자열을 제공하지 않으면 Entity Framework는 컨텍스트 클래스에 따라 기본 연결 문자열을 사용합니다. 자세한 내용은 Code First to a New Database를 참조하세요.

컨트롤러 및 뷰 만들기

이제 데이터를 표시하는 웹 페이지를 만듭니다. 데이터를 요청하는 프로세스는 데이터베이스 생성을 자동으로 트리거합니다. 먼저 새 컨트롤러를 만듭니다. 그러나 그렇게 하기 전에 MVC 컨트롤러 스캐폴딩에서 모델 및 컨텍스트 클래스를 사용할 수 있도록 프로젝트를 빌드합니다.

  1. 솔루션 탐색기 컨트롤러 폴더를 마우스 오른쪽 단추로 클릭하고 추가를 선택한 다음 새 스캐폴드 항목을 클릭합니다.

  2. 스캐폴드 추가 대화 상자에서 Entity Framework를 사용하여 보기가 있는 MVC 5 컨트롤러를 선택한 다음 추가를 선택합니다.

    Visual Studio에서 스캐폴드 추가 대화 상자

  3. 컨트롤러 추가 대화 상자에서 다음을 선택하고 추가를 선택합니다.

    • 모델 클래스: Student(ContosoUniversity.Models). (드롭다운 목록에 이 옵션이 표시되지 않으면 프로젝트를 빌드하고 다시 시도하세요.)

    • 데이터 컨텍스트 클래스: SchoolContext(ContosoUniversity.DAL).

    • 컨트롤러 이름: StudentController (StudentsController 아님).

    • 다른 필드의 기본값을 그대로 둡니다.

      추가를 클릭하면 스캐폴더가 StudentController.cs 파일과 컨트롤러와 함께 작동하는 뷰 집합(.cshtml 파일)을 만듭니다. 나중에 Entity Framework를 사용하는 프로젝트를 만들 때 스캐폴더의 몇 가지 추가 기능을 활용할 수도 있습니다. 첫 번째 모델 클래스를 만들고 연결 문자열을 만들지 마세요. 그런 다음 컨트롤러 추가 상자에서 데이터 컨텍스트 클래스 옆에 있는 단추를 선택하여 새 데이터 컨텍스트+ 지정합니다. 스캐폴더는 컨트롤러 및 뷰뿐만 아니라 클래스와 연결 문자열을 만듭니 DbContext 다.

  4. Visual Studio에서 Controllers\StudentController.cs 파일을 엽니다. 데이터베이스 컨텍스트 개체를 인스턴스화하는 클래스 변수가 만들어진 것을 볼 수 있습니다.

    private SchoolContext db = new SchoolContext();
    

    작업 메서드는 Index 데이터베이스 컨텍스트 instance 속성을 읽 Students학생 엔터티 집합에서 학생 목록을 가져옵니다.

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

    Student\Index.cshtml 보기는 테이블에 이 목록을 표시합니다.

    <table>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.LastName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.FirstMidName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.EnrollmentDate)
            </th>
            <th></th>
        </tr>
    
    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.LastName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.FirstMidName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.EnrollmentDate)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
                @Html.ActionLink("Details", "Details", new { id=item.ID }) |
                @Html.ActionLink("Delete", "Delete", new { id=item.ID })
            </td>
        </tr>
    }
    
  5. Ctrl+F5를 눌러 프로젝트를 실행합니다. ("섀도 복사본을 만들 수 없음" 오류가 발생하면 브라우저를 닫고 다시 시도하세요.)

    학생 탭을 클릭하여 메서드가 Seed 삽입한 테스트 데이터를 확인합니다. 브라우저 창이 얼마나 좁은지에 따라 위쪽 주소 표시줄에 학생 탭 링크가 표시되거나 오른쪽 위 모서리를 클릭하여 링크를 확인해야 합니다.

    메뉴 버튼

데이터베이스 보기

학생 페이지를 실행하고 애플리케이션이 데이터베이스에 액세스하려고 할 때 EF는 데이터베이스가 없다는 것을 발견하고 데이터베이스를 만들었습니다. 그런 다음, EF는 시드 메서드를 실행하여 데이터베이스를 데이터로 채웁습니다.

Server Explorer 또는 SSOX(SQL Server 개체 탐색기)를 사용하여 Visual Studio에서 데이터베이스를 볼 수 있습니다. 이 자습서에서는 Server Explorer 사용합니다.

  1. 브라우저를 닫습니다.

  2. 서버 Explorer데이터 연결을 확장하고(새로 고침 단추를 먼저 선택해야 할 수도 있음), 학교 컨텍스트(ContosoUniversity)를 확장한 다음 테이블을 확장하여 새 데이터베이스의 테이블을 확인합니다.

  3. Student 테이블을 마우스 오른쪽 단추로 클릭하고 테이블 데이터 표시를 클릭하여 생성된 열과 테이블에 삽입된 행을 확인합니다.

  4. 서버 Explorer 연결을 닫습니다.

ContosoUniversity1.mdf.ldf 데이터베이스 파일은 %USERPROFILE% 폴더에 있습니다.

이니셜라이저를 DropCreateDatabaseIfModelChanges 사용하므로 이제 클래스를 변경하고 Student 애플리케이션을 다시 실행하면 변경 내용에 맞게 데이터베이스가 자동으로 다시 만들어집니다. 예를 들어 클래스에 EmailAddressStudent 속성을 추가하고 Students 페이지를 다시 실행한 다음 테이블을 다시 보면 새 EmailAddress 열이 표시됩니다.

규칙

Entity Framework가 완전한 데이터베이스를 만들 수 있도록 하기 위해 작성해야 했던 코드의 양은 규칙 또는 Entity Framework가 만드는 가정 때문에 최소화됩니다. 그 중 일부는 이미 언급되었거나 사용자의 인식 없이 사용되었습니다.

  • 복수형 형식의 엔터티 클래스 이름이 테이블 이름으로 사용됩니다.
  • 엔터티 속성 이름은 열 이름에 사용됩니다.
  • 명명 ID 된 엔터티 속성 또는 클래스 이름은ID 기본 키 속성으로 인식됩니다.
  • 속성은 이름이 <탐색 속성 이름><기본 키 속성 이름>인 경우 외래 키 속성으로 해석됩니다(예: Student 엔터티의 기본 키가 ID인 경우 Student 탐색 속성의 경우 StudentID). 외래 키 속성의 이름은 동일한 단순한 <기본 키 속성 이름> (예 EnrollmentIDEnrollment : 엔터티의 기본 키가 이므로)으로 지정할 수도 있습니다 EnrollmentID.

규칙을 재정의할 수 있다는 것을 보았습니다. 예를 들어 테이블 이름을 복수화하면 안 되도록 지정했으며 나중에 속성을 외래 키 속성으로 명시적으로 표시하는 방법을 확인할 수 있습니다.

코드 가져오기

완료된 프로젝트 다운로드

추가 리소스

EF 6에 대한 자세한 내용은 다음 문서를 참조하세요.

다음 단계

이 자습서에서는 다음을 수행합니다.

  • MVC 웹앱 만들기
  • 사이트 스타일 설정
  • 설치된 Entity Framework 6
  • 데이터 모델 만들기
  • 데이터베이스 컨텍스트 만들기
  • 테스트 데이터로 DB 초기화
  • LocalDB를 사용하도록 EF 6 설정
  • 컨트롤러 및 뷰 만들기
  • 데이터베이스 보기

다음 문서로 이동하여 컨트롤러 및 뷰에서 CRUD(만들기, 읽기, 업데이트, 삭제) 코드를 검토하고 사용자 지정하는 방법을 알아봅니다.