영화 모델 및 데이터베이스 테이블에 새 필드 추가(VB)

작성자: Rick Anderson

이 자습서에서는 Microsoft Visual Studio의 무료 버전인 Microsoft Visual Web Developer 2010 Express Service Pack 1을 사용하여 ASP.NET MVC 웹 애플리케이션을 빌드하는 기본 사항을 설명합니다. 시작하기 전에 아래에 나열된 필수 구성 요소를 설치했는지 확인합니다. 웹 플랫폼 설치 관리자 링크를 클릭하여 모두 설치할 수 있습니다. 또는 다음 링크를 사용하여 필수 구성 요소를 개별적으로 설치할 수 있습니다.

Visual Web Developer 2010 대신 Visual Studio 2010을 사용하는 경우 Visual Studio 2010 필수 구성 요소 링크를 클릭하여 필수 구성 요소를 설치합니다.

VB.NET 소스 코드가 있는 Visual Web Developer 프로젝트는 이 항목과 함께 사용할 수 있습니다. VB.NET 버전을 다운로드합니다. C#을 선호하는 경우 이 자습서의 C# 버전 으로 전환합니다.

이 섹션에서는 모델 클래스를 몇 가지 변경하고 모델 변경 내용과 일치하도록 데이터베이스 스키마를 업데이트하는 방법을 알아봅니다.

영화 모델에 등급 속성 추가

먼저 기존 Movie 클래스에 새 Rating 속성을 추가합니다. Movie.cs 파일을 열고 다음과 같은 속성을 추가 Rating 합니다.

Public Property Rating() As String

이제 전체 Movie 클래스는 다음 코드와 같습니다.

Public Class Movie
    Public Property ID() As Integer
    Public Property Title() As String
    Public Property ReleaseDate() As Date
    Public Property Genre() As String
    Public Property Price() As Decimal
    Public Property Rating() As String
End Class

디버그>영화 빌드 메뉴 명령을 사용하여 애플리케이션을 다시 컴파일합니다.

이제 클래스를 Model 업데이트했으므로 새 Rating 속성을 지원하려면 \Views\Movies\Index.vbhtml\Views\Movies\Create.vbhtml 뷰 템플릿도 업데이트해야 합니다.

\Views\Movies\Index.vbhtml 파일을 열고 Price 열 바로 다음에 열 제목을 추가 <th>Rating</th> 합니다. 그런 다음 템플릿의 끝 부분에 열을 추가하여 <td> 값을 렌더링합니다 @item.Rating . 다음은 업데이트된 Index.vbhtml 보기 템플릿의 모양입니다.

<table>
    <tr>
        <th>            Title        </th>
        <th>            ReleaseDate        </th>
        <th>            Genre        </th>
        <th>            Price        </th>
        <th>Rating</th>
        <th></th>
    </tr>

@For Each item In Model
    Dim currentItem = item
    @<tr>
        <td>
            @Html.DisplayFor(Function(modelItem) currentItem.Title)
        </td>
        <td>
            @Html.DisplayFor(Function(modelItem) currentItem.ReleaseDate)
        </td>
        <td>
            @Html.DisplayFor(Function(modelItem) currentItem.Genre)
        </td>
        <td>
            @Html.DisplayFor(Function(modelItem) currentItem.Price)
        </td>
         <td>
            @Html.DisplayFor(Function(modelItem) currentItem.Rating)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", New With {.id = currentItem.ID}) |
            @Html.ActionLink("Details", "Details", New With {.id = currentItem.ID}) |
            @Html.ActionLink("Delete", "Delete", New With {.id = currentItem.ID})
        </td>
    </tr>
Next

</table>

다음으로 \Views\Movies\Create.vbhtml 파일을 열고 양식의 끝 부분에 다음 태그를 추가합니다. 이렇게 하면 새 동영상을 만들 때 등급을 지정할 수 있도록 텍스트 상자가 렌더링됩니다.

<div class="editor-label">
     @Html.LabelFor(Function(model) model.Rating)
 </div>
 <div class="editor-field">
     @Html.EditorFor(Function(model) model.Rating)
     @Html.ValidationMessageFor(Function(model) model.Rating)
 </div>

모델 및 데이터베이스 스키마 차이점 관리

이제 새 Rating 속성을 지원하도록 애플리케이션 코드를 업데이트했습니다.

이제 애플리케이션을 실행하고 /Movies URL로 이동합니다. 하지만 이렇게 하면 다음 오류가 표시됩니다.

애플리케이션의 서버 오류를 나타내는 오류가 있는 브라우저 창을 보여 주는 스크린샷

이제 애플리케이션의 업데이트 Movie 된 모델 클래스가 기존 데이터베이스 테이블의 Movie 스키마와 다르기 때문에 이 오류가 표시됩니다. (데이터베이스 테이블에 Rating 열이 없습니다.)

이 자습서의 앞부분에서와 같이 Entity Framework Code First를 사용하여 데이터베이스를 자동으로 만드는 경우 Code First는 데이터베이스의 스키마가 생성된 모델 클래스와 동기화되어 있는지 여부를 추적하는 데 도움이 되는 테이블을 데이터베이스에 추가합니다. 동기화되지 않으면 Entity Framework에서 오류가 발생합니다. 이렇게 하면 개발 시 런타임에 (모호한 오류로) 찾을 수 있는 문제를 더 쉽게 추적할 수 있습니다. 동기화 확인 기능은 방금 본 오류 메시지가 표시되는 원인입니다.

오류를 해결하는 방법에는 두 가지가 있습니다.

  1. Entity Framework에서 새 모델 클래스 스키마에 따라 데이터베이스를 자동으로 삭제하고 다시 만들도록 합니다. 이 방법은 모델과 데이터베이스 스키마를 함께 빠르게 발전할 수 있으므로 테스트 데이터베이스에서 활성 개발을 수행할 때 매우 편리합니다. 하지만 단점은 데이터베이스의 기존 데이터가 손실되므로 프로덕션 데이터베이스에서 이 방법을 사용하지 않으려는 것입니다.
  2. 모델 클래스와 일치하도록 기존 데이터베이스의 스키마를 명시적으로 수정합니다. 이 방법의 장점은 데이터가 유지된다는 점입니다. 이러한 변경을 수동으로 수행하거나 데이터베이스 변경 스크립트를 만들어 수행할 수 있습니다.

이 자습서에서는 첫 번째 방법을 사용합니다. 모델이 변경되면 Entity Framework Code First에서 데이터베이스를 자동으로 다시 만듭니다.

모델 변경 내용에 대한 데이터베이스 자동 Re-Creating

애플리케이션의 모델을 변경할 때마다 Code First가 데이터베이스를 자동으로 삭제하고 다시 만들도록 애플리케이션을 업데이트해 보겠습니다.

참고

경고 개발 또는 테스트 데이터베이스를 사용하는 경우에만 데이터베이스를 자동으로 삭제하고 다시 만드는 방법을 사용하도록 설정해야 하며 실제 데이터가 포함된 프로덕션 데이터베이스에서는 사용하지 않아야 합니다. 프로덕션 서버에서 사용하면 데이터가 손실 될 수 있습니다.

솔루션 탐색기Models 폴더를 마우스 오른쪽 단추로 클릭하고 추가를 선택한 다음 클래스를 선택합니다.

솔루션 탐색기 창을 보여 주는 스크린샷 모델 마우스 오른쪽 단추 클릭 메뉴에서 추가가 선택되고 하위 메뉴에서 클래스가 선택됩니다.

클래스 이름을 "MovieInitializer"로 지정합니다. MovieInitializer 다음 코드를 포함하도록 클래스를 업데이트합니다.

using System;
Imports System
Imports System.Collections.Generic
Imports System.Data.Entity

Namespace MvcMovie.Models
    Public Class MovieInitializer
        Inherits DropCreateDatabaseIfModelChanges(Of MovieDBContext)
        Protected Overrides Sub Seed(ByVal context As MovieDBContext)
            Dim movies = New List(Of Movie) From {
             New Movie With {.Title = "When Harry Met Sally", .ReleaseDate = Date.Parse("1989-1-11"), .Genre = "Romantic Comedy", .Rating = "R", .Price = 7.99D},
             New Movie With {.Title = "Ghostbusters ", .ReleaseDate = Date.Parse("1984-3-13"), .Genre = "Comedy", .Rating = "R", .Price = 8.99D},
             New Movie With {.Title = "Ghostbusters 2", .ReleaseDate = Date.Parse("1986-2-23"), .Genre = "Comedy", .Rating = "R", .Price = 9.99D},
             New Movie With {.Title = "Rio Bravo", .ReleaseDate = Date.Parse("1959-4-15"), .Genre = "Western", .Rating = "R", .Price = 3.99D}}

            movies.ForEach(Function(d) context.Movies.Add(d))
        End Sub
    End Class
End Namespace

클래스는 MovieInitializer 모델 클래스가 변경될 경우 모델에서 사용하는 데이터베이스를 삭제하고 자동으로 다시 생성되도록 지정합니다. 코드에는 데이터베이스를 만들거나 다시 만들 때마다 데이터베이스에 자동으로 추가할 몇 가지 기본 데이터를 지정하는 메서드가 포함되어 Seed 있습니다. 이렇게 하면 모델을 변경할 때마다 수동으로 채울 필요 없이 일부 샘플 데이터로 데이터베이스를 채우는 유용한 방법을 제공합니다.

이제 클래스를 MovieInitializer 정의했으므로 애플리케이션이 실행 될 때마다 모델 클래스가 데이터베이스의 스키마와 다른지 여부를 확인하도록 클래스를 연결하려고 합니다. 이 경우 이니셜라이저를 실행하여 모델과 일치하도록 데이터베이스를 다시 만든 다음 데이터베이스를 샘플 데이터로 채울 수 있습니다.

프로젝트의 루트 MvcMovies 에 있는 Global.asax 파일을 엽니다.

Global.asax 파일에는 프로젝트의 전체 애플리케이션을 정의하는 클래스가 포함되어 있으며 애플리케이션이 처음 시작될 때 실행되는 이벤트 처리기가 포함되어 Application_Start 있습니다.

아래와 같이 메서드를 Application_Start 찾고 메서드의 시작 부분에 호출 Database.SetInitializer 을 추가합니다.

Sub Application_Start()
        System.Data.Entity.Database.SetInitializer(Of MovieDBContext)(New MvcMovie.Models.MovieInitializer())
       
        AreaRegistration.RegisterAllAreas()

        RegisterGlobalFilters(GlobalFilters.Filters)
        RegisterRoutes(RouteTable.Routes)
    End Sub

방금 추가한 MovieDBContext 문은 Database.SetInitializer 스키마와 데이터베이스가 일치하지 않는 경우 instance 사용하는 데이터베이스를 자동으로 삭제하고 다시 만들어야 했음을 나타냅니다. 그리고 보셨듯이 클래스에 지정된 MovieInitializer 샘플 데이터로 데이터베이스도 채워집니다.

Global.asax 파일을 닫습니다.

애플리케이션을 다시 실행하고 /Movies URL로 이동합니다. 애플리케이션이 시작되면 모델 구조가 더 이상 데이터베이스 스키마와 일치하지 않는 것을 감지합니다. 새 모델 구조와 일치하도록 데이터베이스를 자동으로 다시 만들고 샘플 동영상으로 데이터베이스를 채웁니다.

7_MyMovieList_SM

새로 만들기 링크를 클릭하여 새 동영상을 추가합니다. 등급을 추가할 수 있습니다.

7_CreateRioII

만들기를 클릭합니다. 등급을 포함한 새 영화가 이제 영화 목록에 표시됩니다.

7_ourNewMovie_SM

이 섹션에서는 모델 개체를 수정하고 데이터베이스를 변경 내용과 동기화된 상태로 유지하는 방법을 알아보았습니다. 시나리오를 사용해 볼 수 있도록 새로 만든 데이터베이스를 샘플 데이터로 채우는 방법도 알아보았습니다. 다음으로 모델 클래스에 보다 풍부한 유효성 검사 논리를 추가하고 일부 비즈니스 규칙을 적용할 수 있는 방법을 살펴보겠습니다.