login register Sysop! about ME  
qrcode
    최초 작성일 :    2008년 03월 24일
  최종 수정일 :    2008년 03월 26일
  작성자 :    taeyo
  편집자 :    Taeyo(김 태영)
  읽음수 :    43,698

강좌 목록으로 돌아가기

필자의 잡담~

모델과 Entity에 대해서 지인들과 이야기를 나누면서 글을 계속적으로 다듬다보니 강좌가 조금 늦었네요 (늦었다고 말은 하지만, 이전 강좌와의 텀이 일주일도 안되는 부분은 저도 놀랍네요~~)
많은 조언과 의견을 주신 유경상, 안재우 수석에게 감사를 드립니다. 그런 의미에서 한잔?

Model 구성하기

ASP.NET MVC 프레임워크에서 모델(Model)은 핵심 로직을 수행하고 데이터를 조작하는 역할을 담당합니다. 일반적으로 데이터베이스와 같은 데이터 저장소에 존재하는 데이터에 접근하고, 그 데이터에 대해 업무 로직을 수행하는 것이죠. 이러한 모델은 개발하려는 애플리케이션에 맞춰 설계가 되어야 하는 부분이기에 그 형식이 고정되어 있거나 하지 않습니다. 기업 환경의 경우에는 업무 분석을 통해서 산출된 엔터티들의 집합이 이러한 모델에 속하곤 하지만, .NET이 기본적으로 제공하는 DataSet과 같은 형식도 모델로서 다루어질 수 있습니다(여기까지는 MSDN에 나오는 모델에 대한 설명과 큰 차이가 없죠. 하하).

데이터 모델은 여러 개의 클래스로 구성될 수 있는데, 여기에는 업무 분석을 통해 산출된 엔터티 클래스들과 그 엔터티들을 사용하여 데이터를 다루는 기능을 갖는 컨텍스트 클래스 등이 포함될 수 있습니다(경우에 따라서는 컨텍스트가 수행하는 기능이 컨트롤러로 빠지는 경우도 있습니다만, ASP.NET MVC에서는 이도 데이터 모델에 포함하고 있습니다). 엔터티들은 일반적으로 데이터베이스에 존재하는 특정 테이블의 스키마와 유사하긴 합니다만, 항상 그런 것은 아닙니다. 소규모 웹 애플리케이션의 경우는 테이블 스키마를 기반으로 엔터티 클래스를 구성하여 사용해도 크게 문제가 없는 편이지만(이러한 작업을 자동화하기 위한 ORM 도구들을 이용하기도 합니다), 규모가 있는 애플리케이션의 경우는 테이블 스키마를 기반으로 엔터티를 도출하는 것이 오히려 적절하지 않은 경우도 많기 때문에 주의해야 합니다. 데이터베이스 테이블은 관계적 구조로 설계되어 있지만, OOP로 작성되는 엔터티 클래스들은 상속 구조로 설계되기 때문에 구조적인 차이로 인한 보정이 요구되는 것도 있고, 테이블 스키마에 기반한 클래스 설계는 데이터베이스에 대한 종속성을 갖게 하기에 그를 독립적으로 운용하기 위한 고려가 요구되는 등 이러한 모델링은 고민해야 할 다양한 요소들이 존재하기에 간단한 작업이 아닙니다. 해서, 이러한 모델링만을 별도로 수행하는 전문가들 및 기업들도 존재하고 있지요. 사실, 이러한 작업은 기능성 작업의 구현을 좋아라하는 저희 같은 개발자들에게는 다소 지루한 부분이기도 합니다.

해서, 기존의 ASP.NET 웹 애플리케이션을 비롯한 다양한 웹 기반의 프로젝트들(스마트 클라이언트 등)에서는 보편적으로 DataSet을 사용하곤 했습니다. 왜냐구요? DataSet은 그냥 이것 저것 고민하지 않고 쉽게 사용할 수 있으니까요. 사실, 엔터티 기반의 애플리케이션을 개발하는 것은 상당히 많은 자원(시간, 노력, 인원)을 요구하는 편입니다. 뽀대가 난다는 이유로 섣불리 엔터티를 도입하여 배보다 배꼽이 더 커지는 당황스런 경험을 해 본 개발자라면 엔터티 기반의 애플리케이션 개발에 고개를 사정없이 흔들기도 할 것입니다. 그런 의미에서 보면, 엔터티의 적용은 대규모 애플리케이션보다는 소규모 애플리케이션에 오히려 더 부합할 수도 있습니다. 그래서, 오히려 대형일수록 엔터티보다는 DataSet을 더 유용하게 사용하는 것인지도 모릅니다. 엔터티를 사용할 경우에 수반되는 생산성 문제 등 다양한 고민거리들에 대해 이것 저것 고민할 필요가 없으니 말이죠.

그렇기에, 데이터 모델로써 여전히 DataSet을 사용할 수는 있습니다만(그리고, 실제로도 DataSet을 여전히 널리 사용하고 있습니다만), Microsoft는 VS 2008을 기점으로 하여(실은 그 전부터이긴 하지만) 가급적 DataSet보다는 사용자 정의 타입인 엔터티 클래스를 만들어서 사용할 것을 살포시 권유(?)하고 있으며, 심지어, VS 2008에서는 그러한 작업을 자동적으로 해주는(물론, 데이터베이스 테이블 스키마 기반으로) LINQ to SQL이라는 클래스를 제공하고 있기도 합니다. 이는 데이터베이스의 테이블 스키마를 기반으로 엔터티 클래스를 자동으로 만들어주는 ORM(Object-Relational Mapping) 도구라고 보시면 됩니다. 매우 유용하긴 하지만 이를 통해 생성된 엔터티 클래스는 다소 복잡한 환경의 애플리케이션에서는 많은 보정작업이 필요할 수도 있으며, 더불어 병행 개발 시의 참조 문제나 배포관련 문제도 고민거리 중에 하나이기에 면밀히 설계 및 검토한 뒤 사용하셔야 합니다.

엔터티가 여러 측면에서 많은 장점을 가지고 있는 것은 사실입니다만, 그 멋진 모습 이면에는 숨겨진 많은 고민거리들이 존재하고 있기에, 애플리케이션을 엔터티 기반으로 구성하는 것이 최고의 답은 아니라는 점은 명심하시기 바랍니다(이에 대해서는 유경상 수석이 "DataSet 예찬론(?)"이란 가제로 글을 준비하고 있기도 합니다. 문제는 글이 언제 올라오느냐겠죠! 버럭!).

그렇긴 하지만, 저는 이어지는 예제에서 LINQ to SQL Class를 사용해서 엔터티를 생성하여 사용할 예정입니다. 비록 이러한 작업이 대형 규모에서는 오히려 피곤한 방법이 될런 지는 모르겠지만, 일반적인 환경(예를 들면, 태오 사이트 같은 중,소 규모 사이트?)에서는 유용하고 쓸만한 방법이기 때문입니다(그리고, 사용해봐야 뭐가 불편한 것인지도 깨달을 수 있겠죠?).

대부분 엔터프라이즈 환경에 계신 분들은 엔터티 기반으로 개발을 진행하는 경우, 데이터 모델 구성 작업을 위해서 모델링 컨설턴트를 고용한다거나, 자체 TFT를 구성하여 작업을 하셨을 것이니 이미 데이터 모델을 가지고 있는 상태이실 것입니다. ^^ 그렇기에, 그 분들에게는 LINQ to SQL 클래스를 이용하는 별도의 모델 구성 작업은 필요 없을 것입니다.

더불어, 사실 기업 환경(엔터프라이즈라고 주로 불리는)이라 해도 항상 엄청난 규모의 프로젝트만을 하는 것은 아닙니다. 대형 프로젝트라 해도 그 내부적으로는 일반적으로 작은 규모의 애플리케이션들이 많이 존재하는 편이니까요. 그리고, 그러한 작은 프로젝트에서는 이러한 방식(LINQ to SQL 클래스를 사용하여 테이블 스키마 기반으로 모델을 구성하는 방식)으로 모델을 구성하는 것도 충분히 가능합니다(초기 프로젝트 지침서에서는 권장하지 않을지도 모르지만, 사는 게 그렇지 않습니까? 하하). 사실, 거대 프로젝트의 일부이긴 하지만 여러 개의 작은 웹 사이트들로 구성된 애플리케이션을 개발하는 경우에 수 많은 게시판을 주먹구구 식으로 개발해왔던 지난 개발환경을 생각해보면, 이 방식이 생각보다 오히려 많이 사용될 수 있어 보이기도 합니다(사실, 엔터프라이즈 환경에서 LINQ나 LINQ to SQL 관련 기술의 적용은 다소 비관적인 편이긴 합니다만, 세상의 모든 프로젝트가 모두 엔터프라이즈 급인 것은 아닐 뿐더러, 적절하게 사용하면 좋을 곳은 분명히 많을테니 말입니다).

드원 테크놀로지의 유경상 수석과 리필 의존적인 커피타임을 가지면서 이에 대한 의견을 교환하다가 느낀 점을 추가적으로 언급하자면, 제가 LINQ to SQL이 중,소 규모에서 그런대로 쓸만하다고 말씀드린 부분은 웹 애플리케이션을 대상으로 한 의견이라는 것입니다. 스마트 클라이언트나 웹 서비스 연동의 윈도우 애플리케이션의 경우는 사실상 서버에서부터 클라이언트까지 이어지는 이러한 엔터티 라이브러리의 연계에 상당히 많은 고민거리들이 있을 수 있습니다. 사실, 이 문제는 닷넷엑스퍼트의 안재우 수석이 이미 자신의 블로그를 통해서 강조한 적도 있습니다. 다음 컬럼을 한번 읽어보세요(시간이 넉넉치 않으신 분은 그 컬럼의 하단에 LINQ to SQL의 문제를 지적한 부분만을 읽어보셔도 됩니다).

http://blog.naver.com/saltynut/120045036743

LINQ to SQL이 생성해주는 엔터티들 뿐만 아니라 실제 기업 환경에서 요구되는 엔터티들이 데이터베이스에 종속성을 갖는 부분에 대한 고민(설계적인 문제) 외에도 개발 생산성과 관련하여 병행 개발 시의 라이브러리 참조문제 및 운영 측면에서의 배포 문제 등은 현재까지도 꾸준히 이어져 오고 있는 고민거리입니다. 간단하게 설명 드리자면, 개발 중에 데이터베이스 스키마에 변경이 생겼다면(생각보다 이런 일이 현실에서는 자주 일어나죠), 그에 따라 엔터티 라이브러리도 재 빌드가 되어야 할 것이며, 그 라이브러리를 참조하고 있는 애플리케이션들도 모두 재 빌드 해야 한다는 것이죠. 프로젝트가 3-4개 정도인 가벼운 규모라면 '그게 무슨 문제가 돼?'라고 말씀하실 수도 있지만, 프로젝트가 수십 개 혹은 수백 개로 이루어지는 경우에는 이 작업은 대단한 부담이 됩니다. 더불어, 1차 배포가 완료되어 실제로 애플리케이션을 운영 중인 상황에서, 컬럼명이 변경된다거나 스키마에 변경이 가해진다거나 하면 위의 작업을 계속적으로 반복해야 하는 것 뿐만 아니라, 엔터티 라이브러리를 클라이언트에게까지 재 배포(스마트 클라이언트와 같은 윈도우 애플리케이션의 경우) 해야 하는 부담도 존재합니다. 그리고, 이런 작은 수정이 빈번하게 발생하게 된다면(주로 배포 초기에 이런 일이 잦은 편이죠), 이러한 복잡하고도 피곤한 작업을 매번 반복해야만 합니다. 해서, 오히려 개발하는 데 드는 시간보다, 빌드하고 배포하는 데에 더 많은 시간과 노력이 요구됩니다. 결국, 프로젝트 완료 전에 이러한 문제들에 대해서 깔끔하게 대처할 수 있는 방안을 세워놓지 않는다면, 프로젝트 끝나고도 수 개월간 뒤치다꺼리에 치여 살게 될 수 있다는 것이죠.

그래서, 기업 중에는 엔터티를 도입하려다가 중도에 포기하는 경우도 꽤 있으며, 혹은 성공적으로(일단은) 프로젝트를 끝낸 뒤에도 산출된 엔터티 라이브러리를 재사용하지 않는 경우도 있습니다.

해서, LINQ to SQL의 효용성, 더 나아가 엔터티 라이브러리의 효율적인 사용에 대해서는 가볍게 이야기할 수 있는 부분이 아닙니다. 효율성에 대한 고민은 다양한 환경에서 유사하지만 약간씩 다른 경험을 한 여러 전문가들, 선배들, 동료들과 의견을 교환하면서 계속적으로 더 나은 방법을 찾아나가야 하지 않나 합니다. 최고의 방법이 아닌 최선의 방법을 찾기 위해서 말이죠~

누군가 그러더군요. "엔터티를 적용한다는 것은 매우 유용하며 효과적인 것임에는 틀림이 없다. 그러나, 그것을 효과적으로 사용하기 위해 드는 비용은 엔터티를 사용하는 것이 과연 좋은 지를 의심하게 하곤 한다"고요. (호오~ 쓰고 보니 그럴 듯 한걸~)

PS : 오해의 소지가 있을까 봐 덧붙입니다. LINQ 기술에 오로지 LINQ to SQL 만 존재하는 것은 아닙니다. LINQ to XML이나 LINQ to DataSets 등의 기술도 존재하고 있으며 이들은 꽤나 유용할 것으로 보입니다. 그렇기에, LINQ 기술 자체는 상당히 흥미로운 기술이며, 관심을 가져볼 만 합니다. 다음 링크도 한번 참고해 보세요.

http://blogs.msdn.com/charlie/archive/2008/02/28/link-to-everything-a-list-of-linq-providers.aspx

뭔가 태오의 글 답지 않게 추상적이면서, 어려워 보이는 말들이 많았는데요. 역시나 이런 류의 아는 척은 저와는 왠지 어울리지 않는 듯 하네요 하하하.

그럼. 이러니 저러니 하는 복잡한 이야기들은 잠시 뒤로 미뤄놓고요. 이제 데이터 모델을 한번 만들어 보도록 하겠습니다? 원론적인 이야기들은 어차피 강좌와 별도로 꾸준히 토론이 되어야 할 부분일 테니까요.

우선, 데이터베이스가 필요합니다. 그렇다면, SQL 서버와 같은 데이터베이스 서버 제품을 또 설치해야 하는 것일까요? 이미 그러한 데이터베이스 서버를 보유하고 있다면 그를 연결해서 사용하시면 되겠지만, 소프트웨어가 없다고 해서 걱정하실 필요는 없습니다. VS 2008은 기본적으로 SQL Server 2008 Express 버전을 탑재하고 있으므로, 별도의 데이터베이스 서버를 설치하지 않으셔도 일단은 사용이 가능합니다.

다음 그림과 같이 App_Data 폴더에 마우스 우측 클릭하여 새로운 항목(SQL Server 데이터베이스)을 추가하도록 하세요. 저는 데이터베이스 파일의 이름으로 MyData.mdf를 주었습니다만, 이 이름은 여러분이 편한 이름으로 지정하셔도 됩니다.

그리고, 생성된 mdf를 더블 클릭하신 뒤, 비어있는 데이터베이스에 다음 그림을 참고로 하여 테이블을 하나 추가해 주세요. 다만, 테이블의 이름은 Memo로 해주시고, Seq 컬럼은 반드시 키 컬럼으로 잡아주시고, Identity 설정도 Yes(예)로 설정하셔서 자동으로 값이 증가하는 컬럼으로 만들어 주시기 바랍니다. 그리고, TransDate라는 컬럼에 대해서는 기본 값을 getdate() 를 지정하도록 하세요. 그래야, 데이터가 입력될 때 날짜도 현재 시간으로 자동 저장될테니까요.

이제 데이터베이스와 테이블은 준비가 되었네요 ^^; 그렇다면, 만들어진 기념으로 테이블을 열고 2-3건의 데이터를 입력해 두시기 바랍니다. 나중에 출력이 잘 되는지 확인하기 위해서 미리 약간의 데이터가 들어있으면 매우 좋으니까요 ^^ (어떻게 입력하냐고요? 서버 탐색기에서 Memo 테이블을 선택하고 마우스 우측클릭 한 뒤, [테이블 데이터 표시]를 선택하시면 기존 데이터를 살펴볼 수 있을 뿐만 아니라, 입력하실 수도 있습니다) 다음 그림처럼 말이죠.

데이터베이스가 준비되었으니, 이제, 진짜로!! 모델을 만들기 위해서 Models 폴더에 LINQ to SQL 클래스를 하나 생성해 보도록 하겠습니다. Models 폴더에 마우스 우측 클릭을 한 뒤, 새로운 항목을 추가하세요. 다음과 같이 말이죠.

그러면, Memo.dbml 이라는 파일이 Models 폴더에 생성됨과 동시에, VS 2008은 그림과 같이 [개체 관계형 디자이너]를 나타내게 되는데요. 여기에 Memo 테이블을 드래그 앤 드롭하여 올려놓으시면 됩니다.

그리고, 저장! 하시면, VS 2008은 자동으로 테이블 스키마를 기반으로 하여 Memo 클래스와 이 를 이용하여 데이터를 처리할 수 있도록 지원하는 MemoDataContext 클래스를 생성해 줍니다(이를 확인하시려면 Memo.dbml 파일을 확장하여 Memo.designer.cs 파일을 열어보시면 됩니다). 이로써 아주 간단하게 데이터 모델이 만들어진 것입니다. 정말 쉽죠?

다만, 이는 1회성의 생성이기에 자동 생성된 데이터 클래스가 데이터베이스 테이블(Memo)과 동기화가 되거나 하지는 않습니다. 즉, 테이블의 스키마가 변경되었다고 해서 자동으로 Memo 클래스도 변경(즉, 재생성)된다거나, Memo 클래스에 추가 속성을 넣는다고 해서 데이터베이스 테이블에도 그 필드가 반영되지는 않는다는 것이죠. 그렇기에, 테이블 스키마가 변경되면 다시금 위의 작업을 반복하여 Memo 클래스를 재생성 해주어야 합니다(여기서, 여러분은 불편함 중 한 가지를 알게 되신 겁니다). ^^

하지만, LINQ to SQL 클래스를 사용함으로써 매우 쉽게 우리는 사용자 정의 타입을 작성할 수 있었습니다. 그쵸? 그리고, 이로써 이제 데이터베이스와 그를 기반으로 하는 데이터 모델은 준비가 완료되었습니다. 즉, MVC 중 M에 해당하는 부분은 준비가 되었다는 것이지요.

그럼, 이제 컨트롤러를 제작하는 쪽으로 넘어가 보도록 하죠. 물론, 그에 앞서 MVC 프레임워크가 지원하는 URL 매핑 방식을 먼저 이해하고 나서 말이죠~ (그러니깐, 이 말은 다음 강좌는 URL 매핑에 관한 이야기라는 것입니다)


authored by

  goni0607
  2009-09-08(18:03)
캐릭 이미지
감사합니다~
  loobear
  2009-10-08(16:17)
감사합니다..MVC 배우는 데 도대체가 뭔지 몰라서 찾아보게 되었네요.
  kimsajang
  2010-10-14(20:08)
어라.. 연재 업뎃이 좀 오래 걸리네요.
태오님 바뿌신가보내요. ^^

  parkdex
  2017-09-10(13:36)
캐릭 이미지
~~감사합니다

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

로딩 중입니다...

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