4부: 모델 및 데이터 액세스
MVC Music Store는 웹 개발을 위해 ASP.NET MVC 및 Visual Studio를 사용하는 방법을 소개하고 단계별로 설명하는 자습서 애플리케이션입니다.
MVC Music Store는 온라인으로 음악 앨범을 판매하고 기본 사이트 관리, 사용자 로그인 및 쇼핑 카트 기능을 구현하는 간단한 샘플 저장소 구현입니다.
이 자습서 시리즈에서는 ASP.NET MVC Music Store 샘플 애플리케이션을 빌드하기 위해 수행된 모든 단계를 자세히 설명합니다. 4부에서는 모델 및 데이터 액세스를 다룹니다.
지금까지 컨트롤러에서 보기 템플릿으로 "더미 데이터"를 전달했습니다. 이제 실제 데이터베이스를 연결할 준비가 되었습니다. 이 자습서에서는 SQL Server Compact Edition(SQL CE라고도 함)을 데이터베이스 엔진으로 사용하는 방법을 다룹니다. SQL CE는 설치 또는 구성이 필요하지 않은 무료 포함된 파일 기반 데이터베이스이므로 로컬 개발에 매우 편리합니다.
Entity Framework Code-First 사용하여 데이터베이스 액세스
ASP.NET MVC 3 프로젝트에 포함된 EF(Entity Framework) 지원을 사용하여 데이터베이스를 쿼리하고 업데이트합니다. EF는 개발자가 개체 지향 방식으로 데이터베이스에 저장된 데이터를 쿼리하고 업데이트할 수 있는 유연한 ORM(개체 관계형 매핑) 데이터 API입니다.
Entity Framework 버전 4는 code-first라는 개발 패러다임을 지원합니다. 코드 우선을 사용하면 간단한 클래스("일반 오래된" CLR 개체의 POCO라고도 함)를 작성하여 모델 개체를 만들 수 있으며 클래스에서 즉시 데이터베이스를 만들 수도 있습니다.
모델 클래스 변경 내용
이 자습서에서는 Entity Framework의 데이터베이스 만들기 기능을 활용합니다. 하지만 이 작업을 수행하기 전에 모델 클래스를 약간 변경하여 나중에 사용할 몇 가지 항목을 추가해 보겠습니다.
아티스트 모델 클래스 추가
앨범은 아티스트와 연결되므로 아티스트를 설명하는 간단한 모델 클래스를 추가하겠습니다. 아래 표시된 코드를 사용하여 Artist.cs라는 Models 폴더에 새 클래스를 추가합니다.
namespace MvcMusicStore.Models
{
public class Artist
{
public int ArtistId { get; set; }
public string Name { get; set; }
}
}
모델 클래스 업데이트
아래와 같이 Album 클래스를 업데이트합니다.
namespace MvcMusicStore.Models
{
public class Album
{
public int AlbumId { get; set; }
public int GenreId { get; set; }
public int ArtistId { get; set; }
public string Title { get; set; }
public decimal Price { get; set; }
public string AlbumArtUrl { get; set; }
public Genre Genre { get; set; }
public Artist Artist { get; set; }
}
}
다음으로, Genre 클래스를 다음과 같이 업데이트합니다.
using System.Collections.Generic;
namespace MvcMusicStore.Models
{
public partial class Genre
{
public int GenreId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<Album> Albums { get; set; }
}
}
App_Data 폴더 추가
프로젝트에 App_Data 디렉터리를 추가하여 SQL Server Express 데이터베이스 파일을 보관합니다. App_Data 데이터베이스 액세스에 대한 올바른 보안 액세스 권한이 이미 있는 ASP.NET 특수 디렉터리입니다. 프로젝트 메뉴에서 ASP.NET 폴더 추가를 선택한 다음, App_Data.
web.config 파일에서 연결 문자열 만들기
Entity Framework에서 데이터베이스에 연결하는 방법을 알 수 있도록 웹 사이트의 구성 파일에 몇 줄을 추가합니다. 프로젝트의 루트에 있는 Web.config 파일을 두 번 클릭합니다.
아래와 같이 이 파일의 아래쪽으로 스크롤하여 마지막 줄 바로 위에 connectionStrings> 섹션을 추가<합니다.
<connectionStrings>
<add name="MusicStoreEntities"
connectionString="Data Source=|DataDirectory|MvcMusicStore.sdf"
providerName="System.Data.SqlServerCe.4.0"/>
</connectionStrings>
</configuration>
컨텍스트 클래스 추가
Models 폴더를 마우스 오른쪽 단추로 클릭하고 MusicStoreEntities.cs라는 새 클래스를 추가합니다.
이 클래스는 Entity Framework 데이터베이스 컨텍스트를 나타내며, 만들기, 읽기, 업데이트 및 삭제 작업을 처리합니다. 이 클래스의 코드는 다음과 같습니다.
using System.Data.Entity;
namespace MvcMusicStore.Models
{
public class MusicStoreEntities : DbContext
{
public DbSet<Album> Albums { get; set; }
public DbSet<Genre> Genres { get; set; }
}
}
다른 구성, 특수 인터페이스 등이 없습니다. DbContext 기본 클래스를 확장하면 MusicStoreEntities 클래스가 데이터베이스 작업을 처리할 수 있습니다. 이제 해당 속성이 연결되었으므로 모델 클래스에 몇 가지 속성을 추가하여 데이터베이스의 일부 추가 정보를 활용해 보겠습니다.
저장소 카탈로그 데이터 추가
새로 만든 데이터베이스에 "시드" 데이터를 추가하는 Entity Framework의 기능을 활용합니다. 그러면 스토어 카탈로그가 장르, 아티스트 및 앨범 목록으로 미리 채워집니다. 이 자습서의 앞부분에서 사용된 사이트 디자인 파일이 포함된 MvcMusicStore-Assets.zip 다운로드에는 Code라는 폴더에 있는 이 시드 데이터가 포함된 클래스 파일이 있습니다.
코드/모델 폴더 내에서 SampleData.cs 파일을 찾아 아래와 같이 프로젝트의 Models 폴더에 놓습니다.
이제 한 줄의 코드를 추가하여 Entity Framework에 해당 SampleData 클래스에 대해 알려야 합니다. 프로젝트의 루트에서 Global.asax 파일을 두 번 클릭하여 열고 Application_Start 메서드 맨 위에 다음 줄을 추가합니다.
protected void Application_Start()
{
System.Data.Entity.Database.SetInitializer(
new MvcMusicStore.Models.SampleData());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
이 시점에서 프로젝트에 대해 Entity Framework를 구성하는 데 필요한 작업을 완료했습니다.
데이터베이스 쿼리
이제 "더미 데이터"를 사용하는 대신 데이터베이스를 호출하여 모든 정보를 쿼리하도록 StoreController를 업데이트해 보겠습니다. 먼저 StoreController에 필드를 선언하여 storeDB라는 MusicStoreEntities 클래스의 instance 보유합니다.
public class StoreController : Controller
{
MusicStoreEntities storeDB = new MusicStoreEntities();
데이터베이스를 쿼리하도록 Store 인덱스 업데이트
MusicStoreEntities 클래스는 Entity Framework에서 유지 관리되며 데이터베이스의 각 테이블에 대한 컬렉션 속성을 노출합니다. 데이터베이스의 모든 장르를 검색하도록 StoreController의 인덱스 작업을 업데이트해 보겠습니다. 이전에는 문자열 데이터를 하드 코딩하여 이 작업을 수행했습니다. 이제 Entity Framework 컨텍스트 Generes 컬렉션을 대신 사용할 수 있습니다.
public ActionResult Index()
{
var genres = storeDB.Genres.ToList();
return View(genres);
}
이전에 반환한 동일한 StoreIndexViewModel을 계속 반환하므로 보기 템플릿을 변경할 필요가 없습니다. 이제 데이터베이스에서 라이브 데이터를 반환하고 있습니다.
프로젝트를 다시 실행하고 "/Store" URL을 방문하면 이제 데이터베이스의 모든 장르 목록이 표시됩니다.
라이브 데이터를 사용하도록 스토어 찾아보기 및 세부 정보 업데이트
/Store/Browse?genre=[some-genre] 작업 메서드를 사용하여 이름으로 장르를 검색합니다. 동일한 장르 이름에 대해 두 개의 항목이 없어야 하므로 결과를 하나만 예상하므로 를 사용할 수 있습니다. LINQ의 Single() 확장은 다음과 같은 적절한 Genre 개체를 쿼리합니다(아직 입력하지 않음).
var example = storeDB.Genres.Single(g => g.Name == "Disco");
Single 메서드는 람다 식을 매개 변수로 사용합니다. 이 매개 변수는 이름이 정의된 값과 일치하게 단일 Genre 개체를 사용하도록 지정합니다. 위의 경우 Disco와 일치하는 Name 값을 사용하여 단일 Genre 개체를 로드합니다.
Genre 개체를 검색할 때 로드하려는 다른 관련 엔터티를 나타낼 수 있는 Entity Framework 기능을 활용합니다. 이 기능을 쿼리 결과 셰이핑이라고 하며 필요한 모든 정보를 검색하기 위해 데이터베이스에 액세스하는 데 필요한 횟수를 줄일 수 있습니다. 검색한 장르용 앨범을 미리 가져오려고 하므로 Genres.Include("Albums")에서 포함하도록 쿼리를 업데이트하여 관련 앨범도 원한다는 것을 나타냅니다. 단일 데이터베이스 요청에서 장르 및 앨범 데이터를 모두 검색하므로 더 효율적입니다.
설명과 함께 업데이트된 컨트롤러 찾아보기 작업이 표시되는 방식은 다음과 같습니다.
public ActionResult Browse(string genre)
{
// Retrieve Genre and its Associated Albums from database
var genreModel = storeDB.Genres.Include("Albums")
.Single(g => g.Name == genre);
return View(genreModel);
}
이제 스토어 찾아보기 보기를 업데이트하여 각 장르에서 사용할 수 있는 앨범을 표시할 수 있습니다. 보기 템플릿(/Views/Store/Browse.cshtml에 있는)을 열고 아래와 같이 글머리 기호로 표시된 앨범 목록을 추가합니다.
@model MvcMusicStore.Models.Genre
@{
ViewBag.Title = "Browse";
}
<h2>Browsing Genre: @Model.Name</h2>
<ul>
@foreach (var album in Model.Albums)
{
<li>
@album.Title
</li>
}
</ul>
애플리케이션을 실행하고 /Store/Browse?genre=Jazz로 이동하면 이제 데이터베이스에서 결과가 끌어오고 선택한 장르의 모든 앨범이 표시됩니다.
/Store/Details/[id] URL을 동일하게 변경하고, ID가 매개 변수 값과 일치하는 앨범을 로드하는 데이터베이스 쿼리로 더미 데이터를 바꿉니다.
public ActionResult Details(int id)
{
var album = storeDB.Albums.Find(id);
return View(album);
}
애플리케이션을 실행하고 /Store/Details/1로 검색하면 이제 결과가 데이터베이스에서 끌어오고 있음을 보여줍니다.
이제 앨범 ID로 앨범을 표시하도록 스토어 세부 정보 페이지가 설정되었으므로 찾아보기 보기를 업데이트하여 세부 정보 보기에 연결해 보겠습니다. 이전 섹션의 끝에 있는 스토어 인덱스에서 스토어 찾아보기로 연결하는 것과 똑같이 Html.ActionLink를 사용합니다. 찾아보기 보기의 전체 원본은 아래에 표시됩니다.
@model MvcMusicStore.Models.Genre
@{
ViewBag.Title = "Browse";
}
<h2>Browsing Genre: @Model.Name</h2>
<ul>
@foreach (var album in Model.Albums)
{
<li>
@Html.ActionLink(album.Title,
"Details", new { id = album.AlbumId })
</li>
}
</ul>
이제 Microsoft Store 페이지에서 사용 가능한 앨범을 나열하는 장르 페이지로 찾아볼 수 있으며, 앨범을 클릭하면 해당 앨범에 대한 세부 정보를 볼 수 있습니다.