"컴파일 타임에 할 수 있는 일을 런타임까지 미루지 마세요."
David Gries, 디지털 컴퓨터용 컴파일러 구성
소개
프로그래머로서 우리가 새로운 기술을 배울 때 예제는 때때로 가장 큰 적이 될 수 있습니다. 지침은 간단하고 이해하기 쉽게 설계되는 경우가 많지만 동시에 게으르고 비효율적이며 심지어 위험한 코드 작성이 증가할 수도 있습니다. 이와 같은 가장 일반적인 상황은 ADO.NET 패러다임에서 발생합니다. 이 기사에서는 예제가 부족함에도 불구하고 데이터베이스에 강력한 형식의 개체가 있다는 것이 무엇을 의미하는지 살펴보겠습니다. 이를 통해 프로그램에서 그렇게 할 수 있습니다.
좀 더 구체적으로 Visual Studio 2005에서 강력한 형식의 데이터 세트가 어떻게 생성되고 사용되는지 살펴보겠습니다. 이 기사에서 살펴본 것처럼 강력한 형식의 데이터 세트는 약한 형식의 다른 데이터 액세스 기술에 비해 많은 이점을 제공합니다. 또한 여기서는 Visual Studio 2005에서는 강력한 형식의 데이터 세트를 만들고 사용하는 것이 더 쉬워지지 않는다는 점을 살펴보겠습니다. 더 자세히 알아보고 싶다면 계속 읽어보세요.
강력한 유형의 개체의 기본 및 이점
강력한 유형의 의미를 이해하려면 먼저 데이트에 대해 생각해 볼 수 있습니다. 싱글이라면 어떤 유형의 사람과 데이트를 고려하시겠습니까? 당신은 특정한 기준(건강하고 매력적이라는 등)을 가질 수도 있고, 그 기준이 단순하거나 불분명할 수도 있습니다. 귀하의 상태가 어떠하든, 누구와 더 많은 시간을 보낼 것인지 결정할 때, 귀하는 항상 이러한 유형에 대한 자신만의 특정 기준을 사용하여 무게를 재고 고려하게 될 것입니다. 당신이 똑똑하다면 정서적 트라우마로부터 자신을 보호하기 위해 많은 생각을 할 것입니다. 예를 들어, 알코올 중독자와 함께 있는 것은 두 사람이 진지한 관계에 있지 않는 한 불안정하다는 것을 알 수 있습니다. 그러나 사람을 변화시키는 것은 고통스럽고 매우 어렵습니다. 그러므로 당신의 지혜는 관계가 시작되기도 전에 관계를 중단하라고 지시할 것입니다. 데이트 기준에 금주 조항을 추가하면 미래의 상심으로부터 당신을 보호하고 더 나은 후보자에게 시간과 에너지를 집중할 수 있습니다.
이 추론이 프로그래밍과 어떤 관련이 있는지 놀랄 수도 있습니다. 상관없어요, 저와 함께 가세요, 사랑스러운 독자님! ADO.NET 데이터 액세스 개체는 매우 유연하게 설계되었습니다. 데이터베이스에서 데이터를 읽을 때 특별한 문제가 발생하지 않는 한 일반 .NET 프레임워크에서 허용하는 여러 일반적인 유형의 개체를 사용하여 작업하게 될 것입니다. 연대 측정 이론을 적용하면 기본적으로 관련 데이터를 보편적 개체로 생각할 수 있습니다. "내 데이트가 그다지 문제가 되지 않는다면 좀 더 명확하게 할 수는 없나요?" 인간이건 다른 생물이건 제한은 없습니다! 여러분의 친구로서 저는 여러분에게 "더 많은 표준을! 목록을 더 작게 만드세요!"라고 간청합니다.
데이트 상대를 무시하면 나중에 관계 문제가 발생할 수 있는 것처럼 코드에서 개체를 선택하지 않은 채로 두면 오류가 발생할 수도 있습니다. 또한 오래된 개체를 서브루틴에서 돌아다니게 하면 프로그램이 실행될 때까지 이것이 문제라는 것을 알아차리지 못할 수도 있습니다. 우리의 데이트 이론을 사용하면 런타임에 오류를 잡는 것은 데이트 상대가 트렌디한 이탈리안 레스토랑 한가운데에서 고통스럽고 어색한 논쟁을 벌이는 것과 같습니다. 예, 미리 계획을 세웠더라면 많은 손님들이 당신을 쳐다보는 일이 없었을 것이고 당황스럽지도 않았을 것입니다. 코드에 더 엄격한 표준을 적용하면 프로그램 컴파일이 시작되기 전에 오류를 잡을 수 있습니다. 예를 들어, 다음 코드 예제는 다음과 같습니다.
string FirstName = myrow.("FirstName").ToString();
이 예제의 DataRow는 형식이 지정되지 않았으므로 필요한 값을 얻으려면 열 이름을 문자열로 사용해야 합니다(또는 레코드의 열 컬렉션에서 열 인덱스를 사용하도록 선택할 수 있습니다). 다행히 해당 열이 존재합니다. DataRow 열의 데이터 유형은 object입니다. FirstName 열의 데이터 유형은 문자열이라고 가정하고 이를 사용하기 전에 명시적으로 문자열로 변환해야 합니다. 이 열의 이름이 변경되면(예: PersonFirstName이 됨) 컴파일러는 이를 알릴 방법이 없습니다. 우울한? 하지만 그럴 필요는 없습니다. 코드가 다음과 같으면 생활이 더 단순해지고 코드의 안정성이 더욱 높아질 것입니다.
string FirstName = PersonRow.FirstName;
이 두 번째 예에서는 강력한 형식의 행을 사용하며 FirstName 속성이 문자열 유형이라는 것을 알고 있습니다. 지저분한 열 이름도 없고 지저분한 유형 변환도 없습니다. 컴파일러는 이미 우리를 위해 유형 검사를 수행했으며, 우리는 열 이름을 올바르게 입력했는지 여부에 대해 걱정하지 않고 안전하게 다른 작업을 수행할 수 있습니다.
다른 모든 것은 동일하므로 제네릭 유형 대신 이것을 사용하는 것을 주저하지 않을 것입니다. 하지만 잠깐만요. 강력한 형식의 개체는 어디서 오는 걸까요? 또한 이러한 개체가 자동으로 생성된다는 점을 말씀드리고 싶습니다. 그러나 좋은 관계에는 시간과 노력이 필요한 것처럼 개체에 강력한 형식을 지정하려면 추가 노력이 필요합니다. 그러나 여기에서 소비한 추가 시간은 확실히 그만한 가치가 있으며 앞으로 "버그를 잡는" 데 소요되는 시간을 기하급수적으로 절약할 수 있습니다.
강력한 유형 지정을 수행하는 방법에는 여러 가지가 있으며, 이 문서의 나머지 부분에서는 Visual Studio 2005에서 강력한 유형의 데이터 세트를 만드는 방법을 설명하겠습니다. 또한 이 접근 방식의 장점과 단점을 다른 접근 방식과 비교해 보겠습니다.
Visual Studio 2005에서 강력한 형식의 데이터 세트 만들기
강력한 형식의 데이터 세트는 실제로 일반 데이터 세트의 미리 정의된 열과 테이블이므로 컴파일러는 여기에 포함된 내용을 이미 알고 있습니다. 야구 글러브처럼 몸에 꼭 맞는 헐렁한 포장지 대신 강력한 형식의 데이터세트가 글러브처럼 딱 맞습니다. Visual Studio의 각 연속 버전을 사용하면 강력한 형식의 데이터 집합을 더 쉽게 처리할 수 있습니다. 다음 예에서는 SQL Server 2005의 AdventureWorks 데이터베이스를 사용합니다. 다음 단계를 따르세요.
1. Visual Studio를 열고 새 ASP.NET 웹사이트를 만듭니다.
2. 솔루션 탐색기 창에서 마우스 오른쪽 버튼을 클릭하여 새 항목을 추가하고 DataSet을 선택합니다. 이름을 AdventureWorks.xsd로 지정합니다(스크린샷 참조). Visual Studio에서는 DataSet 파일을 App_Code 파일에 넣을 것을 권장하며 동의를 클릭하기만 하면 됩니다.
3. 디자인 모드에서 AdventureWorks.xsd를 열면 TableAdapter 구성 마법사가 실행됩니다. 이때 취소를 클릭하면 서버 탐색기에서 원하는 테이블을 끌어서 놓겠습니다.
4. 서버 탐색기 도구 모음에서 AdventureWorks 데이터베이스를 찾습니다. (AdventureWorks 데이터베이스를 설치하지 않은 경우 Microsoft의 다운로드 페이지 SQL Server 2005 샘플 및 샘플 데이터베이스로 이동하여 해당 데이터베이스와 기타 SQL Server 2005 샘플을 다운로드할 수 있습니다.)
5. SalesOrderHeader 테이블과 SalesOrderDetail 테이블을 DataSet 디자인 창으로 끌어 놓습니다. 창은 스크린샷과 같아야 합니다. 우리는 무엇을 보고 있나요? 테이블을 추가할 때마다 Visual Studio는 강력한 형식의 DataTable(원래 테이블과 이름이 동일함)과 TableAdapter를 만듭니다. 이 DataTable은 우리를 위해 각 열을 정의했습니다. TableAdapter는 테이블을 채우는 데 사용하는 것입니다. 기본적으로 원본 테이블에서 각 데이터 행을 가져오는 Fill() 메서드가 있습니다.
그대로, 이 강력한 형식의 데이터 세트는 두 테이블 모두의 모든 레코드를 반환합니다. 하지만 AdventureWorks 데이터베이스에는 많은 주문 정보가 포함되어 있으므로 보다 명시적인 쿼리를 만들어 보는 것은 어떨까요? TableAdapter 개체에 메서드를 추가하여 특정 하위 레코드 집합을 얻을 수 있습니다. SalesORderHeaderTableAdapter를 마우스 오른쪽 버튼으로 클릭하고 Add|Query를 선택합니다. "SQL 문 사용"을 선택하고 다음을 클릭한 후 "행을 반환하는 SELECT"를 선택하고 다음을 클릭합니다. 최근에 창에 다음 쿼리를 입력하십시오(또는 쿼리 빌더를 사용하여 작업을 수행할 수 있음).
선택하다
SalesOrderID, RevisionNumber, OrderDate, DueDate, ShipDate,
상태, OnlineOrderFlag, SalesOrderNumber, BuyOrderNumber,
AccountNumber, CustomerID, ContactID, SalesPersonID, TerritoryID,
BillToAddressID, ShipToAddressID, ShipMethodID, CreditCardID,
CreditCardApprovalCode, CurrentRateID, 소계, TaxAmt, 화물,
TotalDue, Comment, rowguid, ModifiedDate
FROM Sales.SalesOrderHeader
어디서(OrderDate > @OrderDate)
이 SQL 쿼리는 @OrderDate 매개변수를 사용하여 결과를 필터링하는 간단한 SELECT 쿼리입니다. 이렇게 하면 데이터베이스의 모든 레코드를 반환하지 않아도 됩니다. "Fill a DataTable" 및 "Return a DataTable" 확인란을 선택된 상태로 유지하고 Finish를 클릭합니다. 이 SELECT 문을 추가하면 디자이너는 이제 SalesOrderHeaderTableAdapter 아래에 추가 쿼리가 포함된 스크린샷처럼 보일 것입니다.
강력한 형식의 데이터 집합이 설정된 후에는 몇 줄의 코드를 사용하여 ASP.NET 페이지에 데이터를 쉽게 표시할 수 있습니다. 웹 사이트에서 새 ASP.NET 페이지를 만들고 디자인 모드로 전환합니다. GridView 컨트롤을 끌어서 놓고 해당 ID를 GirdView1로 둡니다. 그런 다음 소스 코드 페이지로 이동하여 파일 위에 AdventureWorksTableAdapters 네임스페이스를 추가합니다(C#의 구문은 AdventureWorksTableAdapters를 사용합니다.). 마지막으로 Page_Load 이벤트에 다음 코드를 추가합니다.
// SalesOrderHeaderTableAdapter를 생성합니다.
SalesOrderHeaderTableAdapter salesAdapter =
new SalesOrderHeaderTableAdapter();
// 2004년 7월 1일 이후 발생한 주문을 가져옵니다.
AdventureWorks.SalesOrderHeaderDataTable 주문 =
salesAdapter.GetDataBy(new DateTime(2004, 7, 1));
// 주문 결과를 GridView에 바인딩합니다.
this.GridView1.DataSource = 주문;
this.GridView1.DataBind();
코드는 매우 간단합니다. SalesORderHeaderTableAdapter 인스턴스를 생성하여 데이터 테이블을 채웁니다. 여기서 주목해야 할 점은 일반 DataTable과 달리 SalesORderHeaderDataTable 유형의 개체를 선언하고 GetDateBy() 메서드를 호출하고 DateTime 개체를 전달하여 데이터를 채운다는 것입니다. 또한 여기서 얻은 명령도 강력한 형식이므로 일반 개체 대신 DateTime 개체를 전달해야 합니다. 아래 스크린샷은 위 코드 예제의 결과입니다.
코드를 사용하여 결과 집합을 GridView에 바인딩하는 것 외에도 ObjectDataSource를 사용하고 TypeName 속성을 AdventureWorksTableAdapters.SalesOrderHeaderTableAdapter로 설정하고 SelectMethod를 GetData 또는 GetDataBy로 설정할 수도 있습니다.
데이터베이스에 연결하기 위해 코드를 작성할 필요가 없다는 것 외에도 강력한 형식의 데이터 세트를 사용하는 또 다른 큰 이점은 컴파일러가 확인할 수 없는 코드에 숨어 있는 열 이름 문자열이 없다는 것입니다. 유형 변환도 수행할 필요가 없습니다. 데이터베이스 스키마가 변경되면 AdventureWorks.xsd 파일을 업데이트하기만 하면 관련된 모든 변경 사항이 컴파일 타임에 자동으로 완료됩니다.
강력한 형식의 데이터 액세스 응용 프로그램을 생성하기 위한 기타 기술
강력한 형식의 데이터 세트를 사용하는 것 외에도 프로그램에서 강력한 형식을 구현하는 다른 방법이 있습니다. DataSet보다 더 가볍고 데이터베이스와 더 일관성이 있는 사용자 정의 클래스를 만들 수 있습니다. 이 프로세스를 자동화하는 도구를 개발한 일부 타사 소프트웨어 개발자도 있습니다. 가장 특별하고 제가 가장 좋아하는 것 중 하나는 LLBLGen Pro입니다. 저는 이에 관한 책인 Rapid C# Windows Development: Visual Studio 2005, SQL Server 2005 및 LLBLGen Pro를 쓴 적이 있습니다. (내 웹사이트에서 책의 1/3을 무료로 읽을 수 있습니다.) 또 다른 인기 있는 도구는 CodeSmith입니다. 마이크로소프트도 DLINQ라는 작은 도구를 개발 중이지만 아직 테스트 중이고 적어도 내년까지는 출시되지 않을 것으로 추정된다.
Visual Studio의 강력한 데이터 집합 접근 방식을 사용하는 경우 부인할 수 없는 이점 중 하나는 추가 소프트웨어를 구입할 필요가 없다는 것입니다. 이러한 솔루션은 모두 서로 다른 기능과 이점을 가지고 있지만 주요 이점은 안정성, 오류 감소, 디버깅에 소요되는 시간 단축입니다. 또한 데이터베이스 스키마 변경의 영향을 확인하고 유지 관리를 수행하는 것이 더 쉽습니다. 강력한 타이핑의 이점을 깨달았기를 바랍니다. 발전과 데이트에도 행운을 빕니다!
조셉 챈슬러
첨부 파일
이 기사에서 검토한 코드 다운로드
저자 소개
Joseph Chancellor는 관계적 트라우마를 많이 겪은 남부 캘리포니아의 C# 개발자입니다. 그는 모든 종류의 피드백과 제안을 높이 평가합니다. 그의 블로그를 방문하거나 Visual Studio 2005, SQL Server 2005 및 LLBLGen Pro.
원래 주소: http://aspnet.4guysfromrolla.com/articles/020806-1.aspx