이 자습서의 목표는 ASP.NET MVC 애플리케이션에 대한 모델 클래스를 만드는 한 가지 방법을 설명하는 것입니다. 이 자습서에서는 Microsoft LINQ to SQL 활용하여 모델 클래스를 빌드하고 데이터베이스 액세스를 수행하는 방법을 알아봅니다.
이 자습서의 목표는 ASP.NET MVC 애플리케이션에 대한 모델 클래스를 만드는 한 가지 방법을 설명하는 것입니다. 이 자습서에서는 Microsoft LINQ to SQL 활용하여 모델 클래스를 빌드하고 데이터베이스 액세스를 수행하는 방법을 알아봅니다.
이 자습서에서는 기본 Movie 데이터베이스 애플리케이션을 빌드합니다. 먼저 가능한 가장 빠르고 쉬운 방법으로 Movie 데이터베이스 애플리케이션을 만듭니다. 컨트롤러 작업에서 직접 모든 데이터 액세스를 수행합니다.
다음으로 리포지토리 패턴을 사용하는 방법을 알아봅니다. 리포지토리 패턴을 사용하려면 좀 더 많은 작업이 필요합니다. 그러나 이 패턴을 채택하면 변경에 적응할 수 있고 쉽게 테스트할 수 있는 애플리케이션을 빌드할 수 있다는 장점이 있습니다.
모델 클래스란?
MVC 모델에는 MVC 뷰 또는 MVC 컨트롤러에 포함되지 않은 모든 애플리케이션 논리가 포함됩니다. 특히 MVC 모델에는 모든 애플리케이션 비즈니스 및 데이터 액세스 논리가 포함됩니다.
다양한 기술을 사용하여 데이터 액세스 논리를 구현할 수 있습니다. 예를 들어 Microsoft Entity Framework, NHibernate, Subsonic 또는 ADO.NET 클래스를 사용하여 데이터 액세스 클래스를 빌드할 수 있습니다.
이 자습서에서는 LINQ to SQL 사용하여 데이터베이스를 쿼리하고 업데이트합니다. LINQ to SQL Microsoft SQL Server 데이터베이스와 상호 작용하는 매우 쉬운 방법을 제공합니다. 그러나 ASP.NET MVC 프레임워크가 어떤 식으로든 LINQ to SQL 연결되지 않는다는 것을 이해하는 것이 중요합니다. ASP.NET MVC는 모든 데이터 액세스 기술과 호환됩니다.
무비 데이터베이스 만들기
이 자습서에서는 모델 클래스를 빌드하는 방법을 설명하기 위해 간단한 Movie 데이터베이스 애플리케이션을 빌드합니다. 첫 번째 단계는 새 데이터베이스를 만드는 것입니다. 솔루션 탐색기 창에서 App_Data 폴더를 마우스 오른쪽 단추로 클릭하고 메뉴 옵션 추가, 새 항목을 선택합니다. SQL Server 데이터베이스 템플릿을 선택하고 이름 MoviesDB.mdf를 지정하고 추가 단추를 클릭합니다(그림 1 참조).
그림 01: 새 SQL Server 데이터베이스 추가(전체 크기 이미지를 보려면 클릭)
새 데이터베이스를 만든 후 App_Data 폴더에서 MoviesDB.mdf 파일을 두 번 클릭하여 데이터베이스를 열 수 있습니다. MoviesDB.mdf 파일을 두 번 클릭하면 서버 Explorer 창이 열립니다(그림 2 참조).
Visual Web Developer를 사용할 때 서버 Explorer 창을 데이터베이스 Explorer 창이라고 합니다.
그림 02: 서버 Explorer 창 사용(전체 크기 이미지를 보려면 클릭)
영화를 나타내는 하나의 테이블을 데이터베이스에 추가해야 합니다. Tables 폴더를 마우스 오른쪽 단추로 클릭하고 메뉴 옵션 새 테이블 추가를 선택합니다. 이 메뉴 옵션을 선택하면 테이블 Designer 열립니다(그림 3 참조).
그림 03: 테이블 Designer(전체 크기 이미지를 보려면 클릭)
데이터베이스 테이블에 다음 열을 추가해야 합니다.
열 이름 | 데이터 형식 | Null 허용 |
---|---|---|
Id | Int | 거짓 |
제목 | Nvarchar(200) | 거짓 |
감독 | Nvarchar(50) | 거짓 |
ID 열에 대해 두 가지 특별한 작업을 수행해야 합니다. 먼저 테이블 Designer 열을 선택하고 키 아이콘을 클릭하여 ID 열을 기본 키 열로 표시해야 합니다. LINQ to SQL 데이터베이스에 대해 삽입 또는 업데이트를 수행할 때 기본 키 열을 지정해야 합니다.
다음으로 Id 열을 Id 속성에 예 값을 할당하여 ID 열로 표시해야 합니다(그림 3 참조). ID 열은 테이블에 새 데이터 행을 추가할 때마다 자동으로 새 번호가 할당되는 열입니다.
LINQ to SQL 클래스 만들기
MVC 모델에는 tblMovie 데이터베이스 테이블을 나타내는 LINQ to SQL 클래스가 포함됩니다. 이러한 LINQ to SQL 클래스를 만드는 가장 쉬운 방법은 Models 폴더를 마우스 오른쪽 단추로 클릭하고, 추가, 새 항목을 선택하고, LINQ to SQL 클래스 템플릿을 선택하고, 클래스에 Movie.dbml이라는 이름을 지정하고, 추가 단추를 클릭하는 것입니다(그림 4 참조).
그림 04: LINQ to SQL 클래스 만들기(전체 크기 이미지를 보려면 클릭)
무비 LINQ to SQL 클래스를 만든 직후 개체 관계형 디자이너 나타납니다. 서버 Explorer 창에서 개체 관계형 디자이너 데이터베이스 테이블을 끌어 특정 데이터베이스 테이블을 나타내는 LINQ to SQL 클래스를 만들 수 있습니다. tblMovie 데이터베이스 테이블을 개체 관계형 디자이너 추가해야 합니다(그림 5 참조).
그림 05: 개체 관계형 디자이너 사용(전체 크기 이미지를 보려면 클릭)
기본적으로 개체 관계형 디자이너 Designer 끌어온 데이터베이스 테이블과 이름이 같은 클래스를 만듭니다. 그러나 클래스 tblMovie
를 호출하고 싶지는 않습니다. 따라서 Designer 클래스의 이름을 클릭하고 클래스의 이름을 Movie로 변경합니다.
마지막으로 저장 단추(플로피 그림)를 클릭하여 LINQ to SQL 클래스를 저장해야 합니다. 그렇지 않으면 LINQ to SQL 클래스는 개체 관계형 디자이너 생성되지 않습니다.
컨트롤러 작업에서 LINQ to SQL 사용
이제 LINQ to SQL 클래스가 있으므로 이러한 클래스를 사용하여 데이터베이스에서 데이터를 검색할 수 있습니다. 이 섹션에서는 컨트롤러 작업 내에서 직접 LINQ to SQL 클래스를 사용하는 방법을 알아봅니다. mVC 보기에서 tblMovies 데이터베이스 테이블의 영화 목록을 표시합니다.
먼저 HomeController 클래스를 수정해야 합니다. 이 클래스는 애플리케이션의 Controllers 폴더에서 찾을 수 있습니다. 목록 1의 클래스처럼 보이도록 클래스를 수정합니다.
목록 1 – Controllers\HomeController.cs
using System.Linq;
using System.Web.Mvc;
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
{
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
var dataContext = new MovieDataContext();
var movies = from m in dataContext.Movies
select m;
return View(movies);
}
}
}
목록 1의 작업은 Index()
LINQ to SQL DataContext 클래스()MovieDataContext
를 사용하여 데이터베이스를 MoviesDB
나타냅니다. 클래스는 MoveDataContext
Visual Studio 개체 관계형 디자이너 의해 생성되었습니다.
데이터베이스 테이블에서 모든 영화를 검색하기 위해 DataContext에 대해 LINQ 쿼리가 tblMovies
수행됩니다. 영화 목록은 라는 movies
지역 변수에 할당됩니다. 마지막으로 영화 목록은 보기 데이터를 통해 보기로 전달됩니다.
영화를 표시하려면 다음으로 인덱스 보기를 수정해야 합니다. 폴더에서 인덱스 보기를 Views\Home\
찾을 수 있습니다. 목록 2의 보기처럼 보이도록 인덱스 보기를 업데이트합니다.
목록 2 – Views\Home\Index.aspx
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Home.Index" %>
<%@ Import Namespace="MvcApplication1.Models" %>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<ul>
<% foreach (Movie m in (IEnumerable)ViewData.Model)
{ %>
<li> <%= m.Title %> </li>
<% } %>
</ul>
</asp:Content>
수정된 인덱스 뷰에는 뷰 맨 위에 지시 <%@ import namespace %>
문이 포함되어 있습니다. 이 지시문은 를 MvcApplication1.Models namespace
가져옵니다. 보기에서 클래스( Movie
특히 클래스)를 model
사용하려면 이 네임스페이스가 필요합니다.
목록 2의 보기에는 속성이 foreach
나타내는 모든 항목을 반복하는 루프가 ViewData.Model
포함되어 있습니다. 속성의 Title
값은 각 movie
에 대해 표시됩니다.
속성의 값이 ViewData.Model
로 IEnumerable
캐스팅됩니다. 의 내용을 ViewData.Model
반복하려면 이 작업이 필요합니다. 여기에 있는 또 다른 옵션은 강력한 형식 view
의 를 만드는 것입니다. 강력한 형식 view
의 를 만들 때 뷰의 코드 숨김 클래스에서 속성을 특정 형식으로 캐스팅 ViewData.Model
합니다.
클래스 및 인덱스 보기를 수정한 후 애플리케이션을 HomeController
실행하면 빈 페이지가 표시됩니다. 데이터베이스 테이블에 영화 레코드가 없으므로 빈 페이지가 tblMovies
표시됩니다.
데이터베이스 테이블에 레코드를 tblMovies
추가하려면 서버 Explorer 창(Visual Web Developer의 데이터베이스 Explorer 창)에서 데이터베이스 테이블을 마우스 오른쪽 단추로 클릭하고 tblMovies
테이블 데이터 표시 메뉴 옵션을 선택합니다. 표시되는 그리드를 사용하여 레코드를 삽입 movie
할 수 있습니다(그림 6 참조).
그림 06: 동영상 삽입(전체 크기 이미지를 보려면 클릭)
테이블에 일부 데이터베이스 레코드를 tblMovies
추가하고 애플리케이션을 실행하면 그림 7에 페이지가 표시됩니다. 모든 동영상 데이터베이스 레코드가 글머리 기호 목록에 표시됩니다.
그림 07: 인덱스 보기로 동영상 표시(전체 크기 이미지를 보려면 클릭)
리포지토리 패턴 사용
이전 섹션에서는 컨트롤러 작업 내에서 직접 LINQ to SQL 클래스를 사용했습니다. 컨트롤러 작업에서 직접 클래스를 Index()
사용 MovieDataContext
했습니다. 간단한 애플리케이션의 경우 이 작업을 수행하는 데 아무런 문제가 없습니다. 그러나 컨트롤러 클래스에서 LINQ to SQL 직접 작업하면 더 복잡한 애플리케이션을 빌드해야 할 때 문제가 발생합니다.
컨트롤러 클래스 내에서 LINQ to SQL 사용하면 나중에 데이터 액세스 기술을 전환하기가 어렵습니다. 예를 들어 Microsoft LINQ to SQL 사용에서 Microsoft Entity Framework를 데이터 액세스 기술로 사용하는 것으로 전환할 수 있습니다. 이 경우 애플리케이션 내의 데이터베이스에 액세스하는 모든 컨트롤러를 다시 작성해야 합니다.
컨트롤러 클래스 내에서 LINQ to SQL 사용하면 애플리케이션에 대한 단위 테스트를 빌드하기가 어렵습니다. 일반적으로 단위 테스트를 수행할 때는 데이터베이스와 상호 작용하지 않습니다. 단위 테스트를 사용하여 데이터베이스 서버가 아닌 애플리케이션 논리를 테스트하려고 합니다.
향후 변경에 더 적응할 수 있고 더 쉽게 테스트할 수 있는 MVC 애플리케이션을 빌드하려면 리포지토리 패턴을 사용하는 것이 좋습니다. 리포지토리 패턴을 사용하는 경우 모든 데이터베이스 액세스 논리를 포함하는 별도의 리포지토리 클래스를 만듭니다.
리포지토리 클래스를 만들 때 리포지토리 클래스에서 사용하는 모든 메서드를 나타내는 인터페이스를 만듭니다. 컨트롤러 내에서 리포지토리 대신 인터페이스에 대한 코드를 작성합니다. 이렇게 하면 나중에 다양한 데이터 액세스 기술을 사용하여 리포지토리를 구현할 수 있습니다.
목록 3의 인터페이스 이름은 IMovieRepository
이고 라는 ListAll()
단일 메서드를 나타냅니다.
목록 3 – Models\IMovieRepository.cs
using System.Collections.Generic;
namespace MvcApplication1.Models
{
public interface IMovieRepository
{
IList<Movie> ListAll();
}
}
목록 4의 리포지토리 클래스는 인터페이스를 IMovieRepository
구현합니다. 인터페이스에 필요한 메서드에 해당하는 라는 ListAll()
메서드가 IMovieRepository
포함되어 있습니다.
목록 4 – Models\MovieRepository.cs
using System.Collections.Generic;
using System.Linq;
namespace MvcApplication1.Models
{
public class MovieRepository : IMovieRepository
{
private MovieDataContext _dataContext;
public MovieRepository()
{
_dataContext = new MovieDataContext();
}
#region IMovieRepository Members
public IList<Movie> ListAll()
{
var movies = from m in _dataContext.Movies
select m;
return movies.ToList();
}
#endregion
}
}
마지막으로 목록 5의 MoviesController
클래스는 리포지토리 패턴을 사용합니다. 더 이상 LINQ to SQL 클래스를 직접 사용하지 않습니다.
목록 5 – Controllers\MoviesController.cs
using System.Web.Mvc;
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
{
public class MoviesController : Controller
{
private IMovieRepository _repository;
public MoviesController() : this(new MovieRepository())
{
}
public MoviesController(IMovieRepository repository)
{
_repository = repository;
}
public ActionResult Index()
{
return View(_repository.ListAll());
}
}
}
목록 5의 MoviesController
클래스에는 두 개의 생성자가 있습니다. 첫 번째 생성자인 매개 변수 없는 생성자는 애플리케이션이 실행 중일 때 호출됩니다. 이 생성자는 클래스의 MovieRepository
instance 만들고 두 번째 생성자에 전달합니다.
두 번째 생성자에는 매개 변수인 매개 변수가 하나 있습니다 IMovieRepository
. 이 생성자는 매개 변수 값을 라는 _repository
클래스 수준 필드에 할당하기만 하면 됩니다.
클래스는 MoviesController
종속성 주입 패턴이라는 소프트웨어 디자인 패턴을 활용합니다. 특히 생성자 종속성 주입이라는 항목을 사용하고 있습니다. 이 패턴에 대한 자세한 내용은 Martin Fowler의 다음 문서를 참조하세요.
http://martinfowler.com/articles/injection.html
첫 번째 생성자를 제외하고 클래스의 모든 코드 MoviesController
가 실제 MovieRepository
클래스 대신 인터페이스와 IMovieRepository
상호 작용합니다. 코드는 인터페이스의 구체적인 구현 대신 추상 인터페이스와 상호 작용합니다.
애플리케이션에서 사용하는 데이터 액세스 기술을 수정하려는 경우 대체 데이터베이스 액세스 기술을 사용하는 클래스를 사용하여 인터페이스를 구현 IMovieRepository
하기만 하면 됩니다. 예를 들어 클래스 또는 클래스를 EntityFrameworkMovieRepository
만들 수 있습니다 SubSonicMovieRepository
. 컨트롤러 클래스는 인터페이스에 대해 프로그래밍되므로 의 IMovieRepository
새 구현을 컨트롤러 클래스에 전달할 수 있으며 클래스는 계속 작동합니다.
또한 클래스를 테스트 MoviesController
하려는 경우 가짜 영화 리포지토리 클래스를 에 HomeController
전달할 수 있습니다. 실제로 데이터베이스에 액세스하지 않지만 인터페이스의 IMovieRepository
모든 필수 메서드를 포함하는 클래스를 사용하여 클래스를 구현할 IMovieRepository
수 있습니다. 이렇게 하면 실제로 실제 데이터베이스에 MoviesController
액세스하지 않고 클래스를 단위 테스트할 수 있습니다.
요약
이 자습서의 목표는 Microsoft LINQ to SQL 활용하여 MVC 모델 클래스를 만드는 방법을 보여 주는 것이었습니다. ASP.NET MVC 애플리케이션에서 데이터베이스 데이터를 표시하기 위한 두 가지 전략을 검토했습니다. 먼저 LINQ to SQL 클래스를 만들고 컨트롤러 작업 내에서 직접 클래스를 사용했습니다. 컨트롤러 내에서 LINQ to SQL 클래스를 사용하면 MVC 애플리케이션에서 데이터베이스 데이터를 빠르고 쉽게 표시할 수 있습니다.
다음으로, 데이터베이스 데이터를 표시하기 위해 약간 더 어렵지만 확실히 더 유덕한 경로를 탐색했습니다. 리포지토리 패턴을 활용하고 모든 데이터베이스 액세스 논리를 별도의 리포지토리 클래스에 배치했습니다. 컨트롤러에서 구체적인 클래스 대신 인터페이스에 대해 모든 코드를 작성했습니다. 리포지토리 패턴의 장점은 나중에 데이터베이스 액세스 기술을 쉽게 변경할 수 있고 컨트롤러 클래스를 쉽게 테스트할 수 있다는 것입니다.