데이터 액세스 레이어 만들기(C#)Creating a Data Access Layer (C#)

Scott Mitchellby Scott Mitchell

PDF 다운로드Download PDF

이 자습서에서는 처음부터 시작 하 여 형식화 된 데이터 집합을 사용 하 여 DAL (데이터 액세스 계층)을 만들어 데이터베이스의 정보에 액세스 합니다.In this tutorial we'll start from the very beginning and create the Data Access Layer (DAL), using typed DataSets, to access the information in a database.

소개Introduction

웹 개발자는 데이터 작업을 중심으로 노력 하 고 있습니다.As web developers, our lives revolve around working with data. 데이터를 저장 하는 데이터베이스, 데이터를 검색 및 수정 하는 코드, 데이터를 수집 하 고 요약 하는 웹 페이지를 만듭니다.We create databases to store the data, code to retrieve and modify it, and web pages to collect and summarize it. 이 자습서는 ASP.NET 2.0에서 이러한 일반적인 패턴을 구현 하는 기술을 탐색 하는 긴 시리즈의 첫 번째 자습서입니다.This is the first tutorial in a lengthy series that will explore techniques for implementing these common patterns in ASP.NET 2.0. 형식화 된 데이터 집합을 사용 하 여 DAL (데이터 액세스 계층), 사용자 지정 비즈니스 규칙을 적용 하는 BLL (비즈니스 논리 계층) 및 공통 페이지 레이아웃을 공유 하는 ASP.NET 페이지로 구성 된 프레젠테이션 계층을 사용 하 여 구성 된 소프트웨어 아키텍처 를 만드는 과정을 시작 합니다.We'll start with creating a software architecture composed of a Data Access Layer (DAL) using Typed DataSets, a Business Logic Layer (BLL) that enforces custom business rules, and a presentation layer composed of ASP.NET pages that share a common page layout. 이 백 엔드 기반이 배치 된 후에는 보고로 이동 하 여 웹 응용 프로그램에서 데이터를 표시 하 고, 요약 하 고, 수집 하 고, 유효성을 검사 하는 방법을 보여 줍니다.Once this backend groundwork has been laid, we'll move into reporting, showing how to display, summarize, collect, and validate data from a web application. 이러한 자습서는 간결 하 게 만들어 프로세스를 시각적으로 안내 하는 다양 한 스크린 샷를 제공 하는 단계별 지침을 제공 합니다.These tutorials are geared to be concise and provide step-by-step instructions with plenty of screen shots to walk you through the process visually. 각 자습서는 및 Visual Basic C# 버전에서 사용할 수 있으며, 사용 되는 전체 코드의 다운로드를 포함 합니다.Each tutorial is available in C# and Visual Basic versions and includes a download of the complete code used. 이 첫 번째 자습서는 매우 긴 하지만 나머지는 훨씬 더 좋게 청크로 제공 됩니다.(This first tutorial is quite lengthy, but the rest are presented in much more digestible chunks.)

이러한 자습서에서는 응용 프로그램_데이터 디렉터리에 배치 된 Northwind 데이터베이스의 Microsoft SQL Server 2005 Express Edition 버전을 사용 합니다.For these tutorials we'll be using a Microsoft SQL Server 2005 Express Edition version of the Northwind database placed in the App_Data directory. 데이터베이스 파일 외에도 다른 데이터베이스 버전을 사용 하려는 경우에도 응용 프로그램_Data 폴더에는 데이터베이스를 만들기 위한 SQL 스크립트가 포함 되어 있습니다.In addition to the database file, the App_Data folder also contains the SQL scripts for creating the database, in case you want to use a different database version. 원하는 경우 이러한 스크립트를 Microsoft에서 직접 다운로드할수도 있습니다.These scripts can be also be downloaded directly from Microsoft, if you'd prefer. 다른 SQL Server 버전의 Northwind 데이터베이스를 사용 하는 경우 응용 프로그램의 web.config 파일에서 NORTHWNDConnectionString 설정을 업데이트 해야 합니다.If you use a different SQL Server version of the Northwind database, you will need to update the NORTHWNDConnectionString setting in the application's Web.config file. 웹 응용 프로그램은 Visual Studio 2005 Professional Edition을 파일 시스템 기반 웹 사이트 프로젝트로 사용 하 여 빌드 되었습니다.The web application was built using Visual Studio 2005 Professional Edition as a file system-based Web site project. 그러나 모든 자습서는 visual Studio 2005, Visual Web Developer의 무료 버전과 동일 하 게 작동 합니다.However, all of the tutorials will work equally well with the free version of Visual Studio 2005, Visual Web Developer.

이 자습서에서는 처음부터 시작 하 여 DAL (데이터 액세스 계층)을 만든 다음 두 번째 자습서에서 BLL (비즈니스 논리 계층)을 만들고 세 번째 자습서에서 페이지 레이아웃 및 탐색에 대해 작업을 수행 합니다.In this tutorial we'll start from the very beginning and create the Data Access Layer (DAL), followed by creating the Business Logic Layer (BLL) in the second tutorial, and working on page layout and navigation in the third. 세 번째 자습서의 자습서는 처음 3 개에 배치 된 기반을 바탕으로 작성 됩니다.The tutorials after the third one will build upon the foundation laid in the first three. 이 첫 번째 자습서에 대해 많은 내용이 있으므로 Visual Studio를 실행 하 고 시작 해 보겠습니다.We've got a lot to cover in this first tutorial, so fire up Visual Studio and let's get started!

1 단계: 웹 프로젝트를 만들고 데이터베이스에 연결Step 1: Creating a Web Project and Connecting to the Database

DAL (데이터 액세스 계층)을 만들기 전에 먼저 웹 사이트를 만들고 데이터베이스를 설정 해야 합니다.Before we can create our Data Access Layer (DAL), we first need to create a web site and setup our database. 먼저 새 파일 시스템 기반 ASP.NET 웹 사이트를 만듭니다.Start by creating a new file system-based ASP.NET web site. 이를 위해 파일 메뉴로 이동 하 고 새 웹 사이트를 선택 하 여 새 웹 사이트 대화 상자를 표시 합니다.To accomplish this, go to the File menu and choose New Web Site, displaying the New Web Site dialog box. ASP.NET 웹 사이트 템플릿을 선택 하 고, 위치 드롭다운 목록을 파일 시스템으로 설정 하 고, 웹 사이트를 저장할 폴더를 선택 하 고, 언어를로 C#설정 합니다.Choose the ASP.NET Web Site template, set the Location drop-down list to File System, choose a folder to place the web site, and set the language to C#.

새 파일 시스템 기반 웹 사이트 만들기Create a New File System-Based Web Site

그림 1: 새 파일 시스템 기반 웹 사이트 만들기 (전체 크기 이미지를 보려면 클릭)Figure 1: Create a New File System-Based Web Site (Click to view full-size image)

그러면 default.aspx ASP.NET 페이지와 앱_데이터 폴더를 사용 하 여 새 웹 사이트를 만듭니다.This will create a new web site with a Default.aspx ASP.NET page and an App_Data folder.

웹 사이트를 만든 후 다음 단계는 Visual Studio의 서버 탐색기에서 데이터베이스에 대 한 참조를 추가 하는 것입니다.With the web site created, the next step is to add a reference to the database in Visual Studio's Server Explorer. 서버 탐색기에 데이터베이스를 추가 하 여 Visual Studio 내에서 테이블, 저장 프로시저, 뷰 등을 추가할 수 있습니다.By adding a database to the Server Explorer you can add tables, stored procedures, views, and so on all from within Visual Studio. 테이블 데이터를 보거나 쿼리 작성기를 통해 직접 또는 그래픽으로 직접 쿼리를 만들 수도 있습니다.You can also view table data or create your own queries either by hand or graphically via the Query Builder. 또한 DAL에 대해 형식화 된 데이터 집합을 작성 하는 경우 Visual Studio에서 형식화 된 데이터 집합을 생성 해야 하는 데이터베이스를 가리키도록 해야 합니다.Furthermore, when we build the Typed DataSets for the DAL we'll need to point Visual Studio to the database from which the Typed DataSets should be constructed. 해당 시점에이 연결 정보를 제공할 수 있지만 Visual Studio는 서버 탐색기에 이미 등록 되어 있는 데이터베이스의 드롭다운 목록을 자동으로 채웁니다.While we can provide this connection information at that point in time, Visual Studio automatically populates a drop-down list of the databases already registered in the Server Explorer.

서버 탐색기에 Northwind 데이터베이스를 추가 하는 단계는 응용 프로그램_데이터 폴더에서 SQL Server 2005 Express Edition 데이터베이스를 사용할지 아니면 대신 사용 하려는 Microsoft SQL Server 2000 또는 2005 데이터베이스 서버 설정이 있는지 여부에 따라 달라 집니다.The steps for adding the Northwind database to the Server Explorer depend on whether you want to use the SQL Server 2005 Express Edition database in the App_Data folder or if you have a Microsoft SQL Server 2000 or 2005 database server setup that you want to use instead.

앱_데이터 폴더에 데이터베이스 사용Using a Database in the App_Data Folder

연결할 SQL Server 2000 또는 2005 데이터베이스 서버가 없거나 데이터베이스 서버에 데이터베이스를 추가 하지 않으려는 경우 다운로드 한 웹 사이트의 App_Data 폴더 (northwnd.mdf)에 있는 SQL Server 2005 Express Edition 버전의 Northwind 데이터베이스를 사용할 수 있습니다 . MDF).If you do not have a SQL Server 2000 or 2005 database server to connect to, or you simply want to avoid having to add the database to a database server, you can use the SQL Server 2005 Express Edition version of the Northwind database that is located in the downloaded website's App_Data folder (NORTHWND.MDF).

앱_데이터 폴더에 배치 된 데이터베이스가 서버 탐색기에 자동으로 추가 됩니다.A database placed in the App_Data folder is automatically added to the Server Explorer. 컴퓨터에 SQL Server 2005 Express Edition 설치 되어 있다고 가정할 경우 이름이 NORTHWND.MDF 인 노드가 표시 되어야 합니다. MDF는 테이블, 뷰, 저장 프로시저 등을 확장 하 고 탐색할 수 있는 서버 탐색기입니다 (그림 2 참조).Assuming you have SQL Server 2005 Express Edition installed on your machine you should see a node named NORTHWND.MDF in the Server Explorer, which you can expand and explore its tables, views, stored procedure, and so on (see Figure 2).

앱_데이터 폴더에는 Microsoft Access .mdb 파일이 포함 될 수도 있습니다 .이 파일은 해당 SQL Server와 마찬가지로 서버 탐색기에 자동으로 추가 됩니다 .The App_Data folder can also hold Microsoft Access .mdb files, which, like their SQL Server counterparts, are automatically added to the Server Explorer. SQL Server 옵션 중 하나를 사용 하지 않으려는 경우 항상 Northwind 데이터베이스 파일의 Microsoft Access 버전을 다운로드 하 여 앱_데이터 디렉터리에 놓을 수 있습니다.If you don't want to use any of the SQL Server options, you can always download a Microsoft Access version of the Northwind database file and drop into the App_Data directory. 그러나 Access 데이터베이스는 SQL Server 처럼 기능이 풍부 하지 않으며 웹 사이트 시나리오에서 사용 하도록 설계 되지 않았습니다.Keep in mind, however, that Access databases aren't as feature-rich as SQL Server, and aren't designed to be used in web site scenarios. 또한 35 개 이상의 자습서 중 몇 가지는 Access에서 지원 하지 않는 특정 데이터베이스 수준 기능을 활용 합니다.Furthermore, a couple of the 35+ tutorials will utilize certain database-level features that aren't supported by Access.

Microsoft SQL Server 2000 또는 2005 데이터베이스 서버의 데이터베이스에 연결Connecting to the Database in a Microsoft SQL Server 2000 or 2005 Database Server

또는 데이터베이스 서버에 설치 된 Northwind 데이터베이스에 연결할 수 있습니다.Alternatively, you may connect to a Northwind database installed on a database server. 데이터베이스 서버에 Northwind 데이터베이스가 아직 설치 되어 있지 않은 경우에는 먼저이 자습서의 다운로드에 포함 된 설치 스크립트를 실행 하거나 Microsoft 웹 사이트에서 직접 SQL Server 2000 버전의 northwind 및 설치 스크립트를 다운로드 하 여 데이터베이스 서버에 추가 해야 합니다.If the database server does not already have the Northwind database installed, you first must add it to database server by running the installation script included in this tutorial's download or by downloading the SQL Server 2000 version of Northwind and installation script directly from Microsoft's web site.

데이터베이스를 설치한 후에는 Visual Studio의 서버 탐색기로 이동 하 여 데이터 연결 노드를 마우스 오른쪽 단추로 클릭 하 고 연결 추가를 선택 합니다.Once you have the database installed, go to the Server Explorer in Visual Studio, right-click on the Data Connections node, and choose Add Connection. 서버 탐색기 표시 되지 않으면 보기/서버 탐색기으로 이동 하거나 Ctrl + Alt + S를 누릅니다.If you don't see the Server Explorer go to the View / Server Explorer, or hit Ctrl+Alt+S. 연결 추가 대화 상자가 표시 됩니다. 여기에서 연결할 서버, 인증 정보 및 데이터베이스 이름을 지정할 수 있습니다.This will bring up the Add Connection dialog box, where you can specify the server to connect to, the authentication information, and the database name. 데이터베이스 연결 정보를 성공적으로 구성 하 고 확인 단추를 클릭 하면 데이터베이스는 데이터 연결 노드 아래에 노드로 추가 됩니다.Once you have successfully configured the database connection information and clicked the OK button, the database will be added as a node underneath the Data Connections node. 데이터베이스 노드를 확장 하 여 테이블, 뷰, 저장 프로시저 등을 탐색할 수 있습니다.You can expand the database node to explore its tables, views, stored procedures, and so on.

데이터베이스 서버의 Northwind 데이터베이스에 대 한 연결 추가

그림 2: 데이터베이스 서버의 Northwind 데이터베이스에 대 한 연결 추가Figure 2: Add a Connection to Your Database Server's Northwind Database

2 단계: 데이터 액세스 계층 만들기Step 2: Creating the Data Access Layer

데이터를 사용 하 여 작업 하는 경우 데이터 관련 논리를 프레젠테이션 계층에 직접 포함 합니다. 웹 응용 프로그램에서는 ASP.NET 페이지가 프레젠테이션 계층을 구성 합니다.When working with data one option is to embed the data-specific logic directly into the presentation layer (in a web application, the ASP.NET pages make up the presentation layer). 이는 ASP.NET 페이지의 코드 부분에서 ADO.NET 코드를 작성 하거나 태그 부분에서 SqlDataSource 컨트롤을 사용 하는 형식을 사용할 수 있습니다.This may take the form of writing ADO.NET code in the ASP.NET page's code portion or using the SqlDataSource control from the markup portion. 두 경우 모두이 방법은 데이터 액세스 논리를 프레젠테이션 계층에 긴밀 하 게 결합.In either case, this approach tightly couples the data access logic with the presentation layer. 그러나 권장 되는 방법은 프레젠테이션 계층에서 데이터 액세스 논리를 분리 하는 것입니다.The recommended approach, however, is to separate the data access logic from the presentation layer. 이 별도의 계층은 데이터 액세스 계층 이라고 하 고, 간단 하 게 DAL 하 고, 일반적으로 별도의 클래스 라이브러리 프로젝트로 구현 됩니다.This separate layer is referred to as the Data Access Layer, DAL for short, and is typically implemented as a separate Class Library project. 이 계층화 된 아키텍처의 이점은 잘 문서화 되어 있습니다 (이러한 이점에 대 한 자세한 내용은이 자습서의 끝부분에 있는 "추가 정보" 섹션 참조) .이 시리즈에서 수행할 방법입니다.The benefits of this layered architecture are well documented (see the "Further Readings" section at the end of this tutorial for information on these advantages) and is the approach we will take in this series.

데이터베이스에 대 한 연결 만들기, SELECT, INSERT, UPDATEDELETE 명령 실행 등 기본 데이터 원본에 해당 하는 모든 코드는 DAL에 배치 해야 합니다.All code that is specific to the underlying data source such as creating a connection to the database, issuing SELECT, INSERT, UPDATE, and DELETE commands, and so on should be located in the DAL. 프레젠테이션 계층은 이러한 데이터 액세스 코드에 대 한 참조를 포함 하지 않아야 합니다. 대신 모든 데이터 요청에 대해 DAL을 호출 해야 합니다.The presentation layer should not contain any references to such data access code, but should instead make calls into the DAL for any and all data requests. 데이터 액세스 계층은 일반적으로 기본 데이터베이스 데이터에 액세스 하기 위한 메서드를 포함 합니다.Data Access Layers typically contain methods for accessing the underlying database data. 예를 들어 Northwind 데이터베이스에는 판매 제품과 해당 제품이 속한 범주를 기록 하는 제품범주 테이블이 있습니다.The Northwind database, for example, has Products and Categories tables that record the products for sale and the categories to which they belong. DAL에는 다음과 같은 메서드가 있습니다.In our DAL we will have methods like:

  • Getcategories () -모든 범주에 대 한 정보를 반환 합니다.GetCategories(), which will return information about all of the categories
  • Getproducts () -모든 제품에 대 한 정보를 반환 합니다.GetProducts(), which will return information about all of the products
  • GetProductsByCategoryID (categoryID) -지정 된 범주에 속하는 모든 제품을 반환 합니다.GetProductsByCategoryID(categoryID), which will return all products that belong to a specified category
  • 특정 제품에 대 한 정보를 반환 하는 Getproductid byproductid (productid)GetProductByProductID(productID), which will return information about a particular product

이러한 메서드는 호출 되 면 데이터베이스에 연결 되 고, 적절 한 쿼리를 실행 하 고, 결과를 반환 합니다.These methods, when invoked, will connect to the database, issue the appropriate query, and return the results. 이러한 결과를 반환 하는 방법은 중요 합니다.How we return these results is important. 이러한 메서드는 단순히 데이터베이스 쿼리로 채워진 데이터 집합 또는 DataReader를 반환할 수 있지만, 강력한 형식의 개체를 사용 하 여 이러한 결과를 반환 해야 합니다.These methods could simply return a DataSet or DataReader populated by the database query, but ideally these results should be returned using strongly-typed objects. 강력한 형식의 개체는 스키마가 컴파일 시간에 정의 된 엄격 반면, 느슨하게 형식화 된 개체는 런타임이 될 때까지 알 수 없는 스키마가 있는 개체입니다.A strongly-typed object is one whose schema is rigidly defined at compile time, whereas the opposite, a loosely-typed object, is one whose schema is not known until runtime.

예를 들어 DataReader와 데이터 집합 (기본적으로)은 스키마가 해당 스키마를 채우는 데 사용 되는 데이터베이스 쿼리에서 반환 된 열에 의해 정의 되므로 느슨하게 형식화 된 개체입니다.For example, the DataReader and the DataSet (by default) are loosely-typed objects since their schema is defined by the columns returned by the database query used to populate them. 느슨하게 형식화 된 DataTable에서 특정 열에 액세스 하려면 Datatable과 같은 구문을 사용 해야 합니다. 행 [index] ["columnName"].To access a particular column from a loosely-typed DataTable we need to use syntax like: DataTable.Rows[index]["columnName"]. 이 예에서 DataTable의 느슨한 입력은 문자열 또는 서 수 인덱스를 사용 하 여 열 이름에 액세스 해야 한다는 사실에 의해 제공 됩니다.The DataTable's loose typing in this example is exhibited by the fact that we need to access the column name using a string or ordinal index. 반면 강력한 형식의 DataTable은 각 열을 속성으로 구현 하 여 다음과 같은 코드를 생성 합니다. datatable. 행 [index]. columnName .A strongly-typed DataTable, on the other hand, will have each of its columns implemented as properties, resulting in code that looks like: DataTable.Rows[index].columnName.

강력한 형식의 개체를 반환 하기 위해 개발자는 고유한 사용자 지정 비즈니스 개체를 만들거나 형식화 된 데이터 집합을 사용할 수 있습니다.To return strongly-typed objects, developers can either create their own custom business objects or use Typed DataSets. 비즈니스 개체는 개발자가 일반적으로 비즈니스 개체가 나타내는 기본 데이터베이스 테이블의 열을 반영 하는 클래스로 구현 됩니다.A business object is implemented by the developer as a class whose properties typically reflect the columns of the underlying database table the business object represents. 형식화 된 데이터 집합은 데이터베이스 스키마에 따라 Visual Studio에서 생성 하는 클래스로,이 스키마에 따라 해당 멤버를 강력 하 게 형식화 합니다.A Typed DataSet is a class generated for you by Visual Studio based on a database schema and whose members are strongly-typed according to this schema. 형식화 된 데이터 집합 자체는 ADO.NET DataSet, DataTable 및 DataRow 클래스를 확장 하는 클래스로 구성 됩니다.The Typed DataSet itself consists of classes that extend the ADO.NET DataSet, DataTable, and DataRow classes. 강력한 형식의 Datatable 외에도, 이제 형식화 된 데이터 집합에는 데이터 집합의 Datatable를 채우고 Datatable 내의 수정 내용을 데이터베이스에 다시 전파 하는 메서드를 사용 하는 Tableadapter가 포함 됩니다.In addition to strongly-typed DataTables, Typed DataSets now also include TableAdapters, which are classes with methods for populating the DataSet's DataTables and propagating modifications within the DataTables back to the database.

Note

형식화 된 데이터 집합 및 사용자 지정 비즈니스 개체 사용의 장점과 단점에 대 한 자세한 내용은 데이터 계층 구성 요소 디자인 및 계층을 통해 데이터 전달을 참조 하세요.For more information on the advantages and disadvantages of using Typed DataSets versus custom business objects, refer to Designing Data Tier Components and Passing Data Through Tiers.

이러한 자습서의 아키텍처에 대해 강력한 형식의 데이터 집합을 사용 합니다.We'll use strongly-typed DataSets for these tutorials' architecture. 그림 3에서는 형식화 된 데이터 집합을 사용 하는 응용 프로그램의 다양 한 계층 간 워크플로를 보여 줍니다.Figure 3 illustrates the workflow between the different layers of an application that uses Typed DataSets.

모든 데이터 액세스 코드 DAL에 RelegatedAll Data Access Code is Relegated to the DAL

그림 3: 모든 데이터 액세스 코드가 DAL에 Relegated (전체 크기 이미지를 보려면 클릭)Figure 3: All Data Access Code is Relegated to the DAL (Click to view full-size image)

형식화 된 데이터 집합 및 테이블 어댑터 만들기Creating a Typed DataSet and Table Adapter

DAL을 만들기 시작 하려면 먼저 프로젝트에 형식화 된 데이터 집합을 추가 합니다.To begin creating our DAL, we start by adding a Typed DataSet to our project. 이를 수행 하려면 솔루션 탐색기에서 프로젝트 노드를 마우스 오른쪽 단추로 클릭 하 고 새 항목 추가를 선택 합니다.To accomplish this, right-click on the project node in the Solution Explorer and choose Add a New Item. 템플릿 목록에서 데이터 집합 옵션을 선택 하 고 이름을 Northwind .xsd로 표시 합니다.Select the DataSet option from the list of templates and name it Northwind.xsd.

프로젝트에 새 데이터 집합을 추가 선택 합니다.Choose to Add a New DataSet to Your Project

그림 4: 프로젝트에 새 데이터 집합을 추가 하도록 선택 (전체 크기 이미지를 보려면 클릭)Figure 4: Choose to Add a New DataSet to Your Project (Click to view full-size image)

추가를 클릭 한 후 응용 프로그램_코드 폴더에 데이터 집합을 추가 하 라는 메시지가 표시 되 면 예를 선택 합니다.After clicking Add, when prompted to add the DataSet to the App_Code folder, choose Yes. 그러면 형식화 된 데이터 집합에 대 한 디자이너가 표시 되 고 TableAdapter 구성 마법사가 시작 되어 형식화 된 데이터 집합에 첫 번째 TableAdapter를 추가할 수 있습니다.The Designer for the Typed DataSet will then be displayed, and the TableAdapter Configuration Wizard will start, allowing you to add your first TableAdapter to the Typed DataSet.

형식화 된 데이터 집합은 강력한 형식의 데이터 컬렉션으로 사용 됩니다. 강력한 형식의 DataTable 인스턴스로 구성 되며, 각각은 강력한 형식의 DataRow 인스턴스로 구성 됩니다.A Typed DataSet serves as a strongly-typed collection of data; it is composed of strongly-typed DataTable instances, each of which is in turn composed of strongly-typed DataRow instances. 이 자습서 시리즈에서 작업 해야 하는 기본 데이터베이스 테이블 각각에 대해 강력한 형식의 DataTable을 만듭니다.We will create a strongly-typed DataTable for each of the underlying database tables that we need to work with in this tutorials series. Products 테이블에 대해 DataTable을 만드는 것부터 시작 해 보겠습니다.Let's start with creating a DataTable for the Products table.

강력한 형식의 Datatable는 기본 데이터베이스 테이블에서 데이터에 액세스 하는 방법에 대 한 정보를 포함 하지 않습니다.Keep in mind that strongly-typed DataTables do not include any information on how to access data from their underlying database table. 데이터를 검색 하 여 DataTable을 채울 수 있도록 데이터 액세스 계층으로 작동 하는 TableAdapter 클래스를 사용 합니다.In order to retrieve the data to populate the DataTable, we use a TableAdapter class, which functions as our Data Access Layer. Products DataTable의 경우, TableAdapter는 getproducts () , Getproducts bycategoryid (categoryid) 등의 메서드를 포함 하며,이는 프레젠테이션 계층에서 호출 됩니다.For our Products DataTable, the TableAdapter will contain the methods GetProducts(), GetProductByCategoryID(categoryID), and so on that we'll invoke from the presentation layer. DataTable의 역할은 계층 간에 데이터를 전달 하는 데 사용 되는 강력한 형식의 개체 역할을 수행 하는 것입니다.The DataTable's role is to serve as the strongly-typed objects used to pass data between the layers.

TableAdapter 구성 마법사는 작업할 데이터베이스를 선택 하 라는 메시지를 표시 하기 시작 합니다.The TableAdapter Configuration Wizard begins by prompting you to select which database to work with. 드롭다운 목록에 서버 탐색기의 해당 데이터베이스가 표시 됩니다.The drop-down list shows those databases in the Server Explorer. 서버 탐색기에 Northwind 데이터베이스를 추가 하지 않은 경우 새 연결 단추를 클릭 하 여이 작업을 수행할 수 있습니다.If you did not add the Northwind database to the Server Explorer, you can click the New Connection button at this time to do so.

드롭다운 목록에서 Northwind 데이터베이스를 선택 Choose the Northwind Database from the Drop-Down List

그림 5: 드롭다운 목록에서 Northwind 데이터베이스 선택 (전체 크기 이미지를 보려면 클릭)Figure 5: Choose the Northwind Database from the Drop-Down List (Click to view full-size image)

데이터베이스를 선택 하 고 다음을 클릭 한 후에는 web.config 파일에 연결 문자열을 저장할지 여부를 묻는 메시지가 표시 됩니다.After selecting the database and clicking Next, you'll be asked if you want to save the connection string in the Web.config file. 연결 문자열을 저장 하면 TableAdapter 클래스에 하드 코딩 되지 않으므로 연결 문자열 정보가 나중에 변경 되는 경우 작업이 간단해 집니다.By saving the connection string you'll avoid having it hard coded in the TableAdapter classes, which simplifies things if the connection string information changes in the future. 구성 파일에 연결 문자열을 저장 하도록 선택 하는 경우 <connectionStrings> 섹션에 배치 됩니다 .이 섹션은 나중에 IIS GUI 관리 도구 내의 새 ASP.NET 2.0 속성 페이지를 통해 수정 하거나 나중에 수정할 수 있습니다 .이는 관리자에 게 보다 적합 합니다.If you opt to save the connection string in the configuration file it's placed in the <connectionStrings> section, which can be optionally encrypted for improved security or modified later through the new ASP.NET 2.0 Property Page within the IIS GUI Admin Tool, which is more ideal for administrators.

Web.config에 연결 문자열을 저장 Save the Connection String to Web.config

그림 6: Web.config 에 연결 문자열 저장 (전체 크기 이미지를 보려면 클릭)Figure 6: Save the Connection String to Web.config (Click to view full-size image)

다음으로 강력한 형식의 데이터 집합을 채울 때 첫 번째 강력한 형식의 DataTable에 대 한 스키마를 정의 하 고 TableAdapter에서 사용할 첫 번째 메서드를 제공 해야 합니다.Next, we need to define the schema for the first strongly-typed DataTable and provide the first method for our TableAdapter to use when populating the strongly-typed DataSet. 이러한 두 단계는 DataTable에 반영 하려는 테이블의 열을 반환 하는 쿼리를 만들어 동시에 수행 됩니다.These two steps are accomplished simultaneously by creating a query that returns the columns from the table that we want reflected in our DataTable. 마법사의 끝 부분에서이 쿼리에 메서드 이름을 지정 합니다.At the end of the wizard we'll give a method name to this query. 이를 완료 한 후에는 프레젠테이션 계층에서이 메서드를 호출할 수 있습니다.Once that's been accomplished, this method can be invoked from our presentation layer. 메서드는 정의 된 쿼리를 실행 하 고 강력한 형식의 DataTable을 채웁니다.The method will execute the defined query and populate a strongly-typed DataTable.

SQL 쿼리 정의를 시작 하려면 먼저 TableAdapter에서 쿼리를 실행 하는 방법을 지정 해야 합니다.To get started defining the SQL query we must first indicate how we want the TableAdapter to issue the query. 임시 SQL 문을 사용 하거나, 새 저장 프로시저를 만들거나, 기존 저장 프로시저를 사용할 수 있습니다.We can use an ad-hoc SQL statement, create a new stored procedure, or use an existing stored procedure. 이러한 자습서에서는 임시 SQL 문을 사용 합니다.For these tutorials we'll use ad-hoc SQL statements. 저장 프로시저 를 사용하는 예는 Visual Studio 2005 데이터 집합 디자이너를 사용 하 여 데이터 액세스 계층 작성 문서를 참조 하세요.Refer to Brian Noyes's article, Build a Data Access Layer with the Visual Studio 2005 DataSet Designer for an example of using stored procedures.

임시 SQL 문을 사용 하 여 데이터를 쿼리 Query the Data Using an Ad-Hoc SQL Statement

그림 7: 임시 SQL 문을 사용 하 여 데이터 쿼리 (전체 크기 이미지를 보려면 클릭)Figure 7: Query the Data Using an Ad-Hoc SQL Statement (Click to view full-size image)

이 시점에서 SQL 쿼리를 직접 입력할 수 있습니다.At this point we can type in the SQL query by hand. TableAdapter에서 첫 번째 메서드를 만들 때 일반적으로 쿼리에서 해당 DataTable에 표시 되어야 하는 열을 반환 하도록 하려고 합니다.When creating the first method in the TableAdapter you typically want to have the query return those columns that need to be expressed in the corresponding DataTable. Products 테이블의 모든 열과 모든 행을 반환 하는 쿼리를 만들어이 작업을 수행할 수 있습니다.We can accomplish this by creating a query that returns all columns and all rows from the Products table:

텍스트 상자에 SQL 쿼리를 입력 .Enter the SQL Query Into the Textbox

그림 8: 텍스트 상자에 SQL 쿼리 입력 (전체 크기 이미지를 보려면 클릭)Figure 8: Enter the SQL Query Into the Textbox (Click to view full-size image)

또는 그림 9와 같이 쿼리 작성기 사용 하 여 쿼리를 그래픽으로 생성 합니다.Alternatively, use the Query Builder and graphically construct the query, as shown in Figure 9.

쿼리 편집기를 통해 쿼리를 그래픽으로 만들 Create the Query Graphically, through the Query Editor

그림 9: 쿼리 편집기를 통해 그래픽으로 쿼리 만들기 (전체 크기 이미지를 보려면 클릭)Figure 9: Create the Query Graphically, through the Query Editor (Click to view full-size image)

쿼리를 만든 후 다음 화면으로 이동 하기 전에 고급 옵션 단추를 클릭 합니다.After creating the query, but before moving onto the next screen, click the Advanced Options button. 웹 사이트 프로젝트에서 "Insert, Update 및 Delete 문 생성"은 기본적으로 선택 되어 있는 유일한 고급 옵션입니다. 클래스 라이브러리나 Windows 프로젝트에서이 마법사를 실행 하는 경우 "낙관적 동시성 사용" 옵션도 선택 됩니다.In Web Site Projects, "Generate Insert, Update, and Delete statements" is the only advanced option selected by default; if you run this wizard from a Class Library or a Windows Project the "Use optimistic concurrency" option will also be selected. 지금은 "낙관적 동시성 사용" 옵션을 선택 하지 않은 상태로 둡니다.Leave the "Use optimistic concurrency" option unchecked for now. 이후 자습서에서 낙관적 동시성을 살펴보겠습니다.We'll examine optimistic concurrency in future tutorials.

Insert, Update 및 Delete 문 생성 옵션만 선택 .Select Only the Generate Insert, Update, and Delete statements Option

그림 10: Insert, Update 및 Delete 문 생성 옵션만 선택 (전체 크기 이미지를 보려면 클릭)Figure 10: Select Only the Generate Insert, Update, and Delete statements Option (Click to view full-size image)

고급 옵션을 확인 한 후 다음을 클릭 하 여 최종 화면으로 이동 합니다.After verifying the advanced options, click Next to proceed to the final screen. TableAdapter에 추가할 메서드를 선택 하 라는 메시지가 표시 됩니다.Here we are asked to select which methods to add to the TableAdapter. 데이터를 채우는 데는 다음과 같은 두 가지 패턴이 있습니다.There are two patterns for populating data:

  • 이 접근 방식을 사용 하 여 datatable을 채웁니다 .이 메서드는 datatable을 매개 변수로 사용 하 고 쿼리 결과에 따라 채웁니다.Fill a DataTable with this approach a method is created that takes in a DataTable as a parameter and populates it based on the results of the query. 예를 들어 ADO.NET DataAdapter 클래스는 Fill () 메서드를 사용 하 여이 패턴을 구현 합니다.The ADO.NET DataAdapter class, for example, implements this pattern with its Fill() method.
  • 이 접근 방식을 사용 하 여 datatable을 반환 합니다. 메서드는 datatable을 만들어 채운 다음 메서드 반환 값으로 반환 합니다.Return a DataTable with this approach the method creates and fills the DataTable for you and returns it as the methods return value.

TableAdapter에서 이러한 패턴 중 하나 또는 둘 모두를 구현할 수 있습니다.You can have the TableAdapter implement one or both of these patterns. 여기에 제공 된 메서드의 이름을 바꿀 수도 있습니다.You can also rename the methods provided here. 이러한 자습서 전체에서 후자의 패턴을 사용 하는 경우에도 두 확인란을 모두 선택 된 상태로 둡니다.Let's leave both checkboxes checked, even though we'll only be using the latter pattern throughout these tutorials. 또한 대신 generic GetData 메서드 이름을 getproducts로 변경 하겠습니다.Also, let's rename the rather generic GetData method to GetProducts.

이 확인란을 선택 하면 "GenerateDBDirectMethods" 라는 마지막 확인란이 TableAdapter에 대해 Insert () , Update ( ) 및 Delete () 메서드를 만듭니다.If checked, the final checkbox, "GenerateDBDirectMethods," creates Insert(), Update(), and Delete() methods for the TableAdapter. 이 옵션을 선택 하지 않은 상태로 두면 형식화 된 데이터 집합, DataTable, 단일 DataRow 또는 Datarow의 배열을 사용 하는 TableAdapter의 유일한 Update () 메서드를 통해 모든 업데이트를 수행 해야 합니다.If you leave this option unchecked, all updates will need to be done through the TableAdapter's sole Update() method, which takes in the Typed DataSet, a DataTable, a single DataRow, or an array of DataRows. (그림 9의 고급 속성에서 "Insert, Update 및 Delete 문 생성" 옵션을 선택 취소 한 경우이 확인란의 설정은 적용 되지 않습니다.) 이 확인란을 선택 해 둡니다.(If you've unchecked the "Generate Insert, Update, and Delete statements" option from the advanced properties in Figure 9 this checkbox's setting will have no effect.) Let's leave this checkbox selected.

메서드 이름을 GetData에서 GetProducts로 변경 Change the Method Name from GetData to GetProducts

그림 11: 메서드 이름을 GetData 에서 getproducts 로 변경 (전체 크기 이미지를 보려면 클릭)Figure 11: Change the Method Name from GetData to GetProducts (Click to view full-size image)

마침을 클릭 하 여 마법사를 완료 합니다.Complete the wizard by clicking Finish. 마법사를 닫으면 방금 만든 DataTable을 보여 주는 데이터 집합 디자이너로 돌아갑니다.After the wizard closes we are returned to the DataSet Designer which shows the DataTable we just created. Products DataTable (ProductID, ProductName등)의 열 목록과 Products stableadapter (Fill ()getproducts () 의 메서드를 볼 수 있습니다.You can see the list of columns in the Products DataTable (ProductID, ProductName, and so on), as well as the methods of the ProductsTableAdapter (Fill() and GetProducts()).

Products DataTable 및 Products Stableadapter가 형식화 된 데이터 집합에 추가 The Products DataTable and ProductsTableAdapter have been Added to the Typed DataSet

그림 12: Products DataTable 및 Products Stableadapter 가 형식화 된 데이터 집합에 추가 되었습니다 (전체 크기 이미지를 보려면 클릭).Figure 12: The Products DataTable and ProductsTableAdapter have been Added to the Typed DataSet (Click to view full-size image)

이 시점에서 Getproducts () 메서드를 사용 하 여 단일 DataTable (NorthwindTableAdapters) 및 강력한 형식의 DataAdapter클래스 ( stableadapter)를 포함 하는 형식화 된 데이터 집합이 있습니다.At this point we have a Typed DataSet with a single DataTable (Northwind.Products) and a strongly-typed DataAdapter class (NorthwindTableAdapters.ProductsTableAdapter) with a GetProducts() method. 이러한 개체를 사용 하 여 코드에서와 같은 모든 제품 목록에 액세스할 수 있습니다.These objects can be used to access a list of all products from code like:

NorthwindTableAdapters.ProductsTableAdapter productsAdapter =
    new NorthwindTableAdapters.ProductsTableAdapter();
Northwind.ProductsDataTable products;
products = productsAdapter.GetProducts();
foreach (Northwind.ProductsRow productRow in products)
    Response.Write("Product: " + productRow.ProductName + "<br />");

이 코드는 데이터 액세스 관련 코드를 하나 이상 작성 하지 않아도 됩니다.This code did not require us to write one bit of data access-specific code. ADO.NET 클래스를 인스턴스화할 필요가 없습니다. 연결 문자열, SQL 쿼리 또는 저장 프로시저를 참조할 필요가 없습니다.We did not have to instantiate any ADO.NET classes, we didn't have to refer to any connection strings, SQL queries, or stored procedures. 대신 TableAdapter는 낮은 수준의 데이터 액세스 코드를 제공 합니다.Instead, the TableAdapter provides the low-level data access code for us.

이 예제에서 사용 되는 각 개체는 강력 하 게 형식화 되어 있으므로 Visual Studio에서 IntelliSense 및 컴파일 시간 형식 검사를 제공할 수 있습니다.Each object used in this example is also strongly-typed, allowing Visual Studio to provide IntelliSense and compile-time type checking. TableAdapter에서 반환 하는 모든 Datatable은 GridView, DetailsView, DropDownList, CheckBoxList 등과 같은 ASP.NET 데이터 웹 컨트롤에 바인딩될 수 있습니다.And best of all the DataTables returned by the TableAdapter can be bound to ASP.NET data Web controls, such as the GridView, DetailsView, DropDownList, CheckBoxList, and several others. 다음 예제에서는 Getproducts () 메서드에 의해 반환 된 DataTable을 페이지_Load 이벤트 처리기에서 scant 세 줄의 코드를 GridView에 바인딩하는 방법을 보여 줍니다.The following example illustrates binding the DataTable returned by the GetProducts() method to a GridView in just a scant three lines of code within the Page_Load event handler.

AllProducts.aspxAllProducts.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="AllProducts.aspx.cs"
    Inherits="AllProducts" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>View All Products in a GridView</title>
    <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h2>
            All Products</h2>
        <p>
            <asp:GridView ID="GridView1" runat="server"
             CssClass="DataWebControlStyle">
               <HeaderStyle CssClass="HeaderStyle" />
               <AlternatingRowStyle CssClass="AlternatingRowStyle" />
            </asp:GridView>
             </p>
    </div>
    </form>
</body>
</html>

AllProducts.aspx.csAllProducts.aspx.cs

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using NorthwindTableAdapters;
public partial class AllProducts : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        ProductsTableAdapter productsAdapter = new
         ProductsTableAdapter();
        GridView1.DataSource = productsAdapter.GetProducts();
        GridView1.DataBind();
    }
}

제품 목록이 GridView에 표시 The List of Products is Displayed in a GridView

그림 13: 제품 목록이 GridView에 표시 됨 (전체 크기 이미지를 보려면 클릭)Figure 13: The List of Products is Displayed in a GridView (Click to view full-size image)

이 예제에서는 ASP.NET 페이지의 페이지_Load 이벤트 처리기에서 3 줄의 코드를 작성 해야 하지만, 이후 자습서에서는 ObjectDataSource를 사용 하 여 DAL에서 데이터를 선언적으로 검색 하는 방법을 살펴보겠습니다.While this example required that we write three lines of code in our ASP.NET page's Page_Load event handler, in future tutorials we'll examine how to use the ObjectDataSource to declaratively retrieve the data from the DAL. ObjectDataSource를 사용 하면 코드를 작성할 필요가 없으며 페이징 및 정렬 지원도 지원 됩니다.With the ObjectDataSource we'll not have to write any code and will get paging and sorting support as well!

3 단계: 데이터 액세스 계층에 매개 변수가 있는 메서드 추가Step 3: Adding Parameterized Methods to the Data Access Layer

이제 제품 Stableadapter 클래스에는 데이터베이스의 모든 제품을 반환 하는 getproducts () 메서드가 하나 있습니다.At this point our ProductsTableAdapter class has but one method, GetProducts(), which returns all of the products in the database. 모든 제품을 사용할 수 있는 것은 매우 유용 하지만 특정 제품 또는 특정 범주에 속하는 모든 제품에 대 한 정보를 검색 하려는 경우가 있습니다.While being able to work with all products is definitely useful, there are times when we'll want to retrieve information about a specific product, or all products that belong to a particular category. 데이터 액세스 계층에 이러한 기능을 추가 하려면 매개 변수가 있는 메서드를 TableAdapter에 추가할 수 있습니다.To add such functionality to our Data Access Layer we can add parameterized methods to the TableAdapter.

GetProductsByCategoryID (categoryID) 메서드를 추가 해 보겠습니다.Let's add the GetProductsByCategoryID(categoryID) method. DAL에 새 메서드를 추가 하려면 데이터 집합 디자이너로 돌아가서, 제품 Stableadapter 섹션을 마우스 오른쪽 단추로 클릭 하 고 쿼리 추가를 선택 합니다.To add a new method to the DAL, return to the DataSet Designer, right-click in the ProductsTableAdapter section, and choose Add Query.

TableAdapter를 마우스 오른쪽 단추로 클릭 하 고 쿼리 추가를 선택 합니다.

그림 14: TableAdapter를 마우스 오른쪽 단추로 클릭 하 고 쿼리 추가를 선택 합니다.Figure 14: Right-Click on the TableAdapter and Choose Add Query

먼저 임시 SQL 문이나 기존 또는 기존 저장 프로시저를 사용 하 여 데이터베이스에 액세스할 지 여부를 묻는 메시지가 표시 됩니다.We are first prompted about whether we want to access the database using an ad-hoc SQL statement or a new or existing stored procedure. 임시 SQL 문을 다시 사용 하도록 선택 합니다.Let's choose to use an ad-hoc SQL statement again. 다음으로, 사용 하고자 하는 SQL 쿼리 유형을 묻는 메시지가 표시 됩니다.Next, we are asked what type of SQL query we'd like to use. 지정 된 범주에 속하는 모든 제품을 반환 하려고 하기 때문에 행을 반환 하는 SELECT 문을 작성 하려고 합니다.Since we want to return all products that belong to a specified category, we want to write a SELECT statement which returns rows.

행을 반환 하는 SELECT 문을 만들도록 선택할 Choose to Create a SELECT Statement Which Returns Rows

그림 15: 행을 반환 하는 SELECT 문 만들기 선택 (전체 크기 이미지를 보려면 클릭)Figure 15: Choose to Create a SELECT Statement Which Returns Rows (Click to view full-size image)

다음 단계는 데이터에 액세스 하는 데 사용 되는 SQL 쿼리를 정의 하는 것입니다.The next step is to define the SQL query used to access the data. 특정 범주에 속하는 제품만 반환 하려고 하므로 Getproducts ()에서 동일한 SELECT 문을 사용 하지만 where CategoryID = @CategoryID where 절을 추가 합니다.Since we want to return only those products that belong to a particular category, I use the same SELECT statement from GetProducts(), but add the following WHERE clause: WHERE CategoryID = @CategoryID. @CategoryID 매개 변수는 만들려는 메서드에 해당 형식의 입력 매개 변수 (즉, nullable 정수)가 필요한 TableAdapter 마법사를 나타냅니다.The @CategoryID parameter indicates to the TableAdapter wizard that the method we're creating will require an input parameter of the corresponding type (namely, a nullable integer).

지정 된 범주의 제품만 반환 하는 쿼리를 입력 .Enter a Query to Only Return Products in a Specified Category

그림 16: 지정 된 범주의 제품만 반환 하는 쿼리 입력 (전체 크기 이미지를 보려면 클릭)Figure 16: Enter a Query to Only Return Products in a Specified Category (Click to view full-size image)

마지막 단계에서는 사용할 데이터 액세스 패턴을 선택 하 고 생성 되는 방법의 이름을 사용자 지정할 수 있습니다.In the final step we can choose which data access patterns to use, as well as customize the names of the methods generated. 채우기 패턴의 경우 이름을 Fillbycategoryid 로 변경 하 고 DataTable 반환 패턴 ( GetX 메서드) 반환에 대해 GetProductsByCategoryID를 사용 하겠습니다.For the Fill pattern, let's change the name to FillByCategoryID and for the return a DataTable return pattern (the GetX methods), let's use GetProductsByCategoryID.

TableAdapter 메서드의 이름을 선택 합니다.Choose the Names for the TableAdapter Methods

그림 17: TableAdapter 메서드의 이름 선택 (전체 크기 이미지를 보려면 클릭)Figure 17: Choose the Names for the TableAdapter Methods (Click to view full-size image)

마법사를 완료 한 후에는 데이터 집합 디자이너에 새 TableAdapter 메서드가 포함 됩니다.After completing the wizard, the DataSet Designer includes the new TableAdapter methods.

이제 제품을 범주별로 쿼리할 수 있습니다.

그림 18: 이제 제품을 범주별로 쿼리할 수 있습니다.Figure 18: The Products Can Now be Queried by Category

동일한 기술을 사용 하 여 Getproductid byproductid (productID) 메서드를 추가 합니다.Take a moment to add a GetProductByProductID(productID) method using the same technique.

이러한 매개 변수가 있는 쿼리는 데이터 집합 디자이너에서 직접 테스트할 수 있습니다.These parameterized queries can be tested directly from the DataSet Designer. TableAdapter에서 메서드를 마우스 오른쪽 단추로 클릭 하 고 데이터 미리 보기를 선택 합니다.Right-click on the method in the TableAdapter and choose Preview Data. 그런 다음 매개 변수에 사용할 값을 입력 하 고 미리 보기를 클릭 합니다.Next, enter the values to use for the parameters and click Preview.

음료 범주에 속한 제품이 표시 됩니다 Those Products Belonging to the Beverages Category are Shown

그림 19: 음료 범주에 속한 제품이 표시 됩니다 (전체 크기 이미지를 보려면 클릭).Figure 19: Those Products Belonging to the Beverages Category are Shown (Click to view full-size image)

DAL에서 GetProductsByCategoryID (categoryID) 메서드를 사용 하 여 이제 지정 된 범주의 제품만 표시 하는 ASP.NET 페이지를 만들 수 있습니다.With the GetProductsByCategoryID(categoryID) method in our DAL, we can now create an ASP.NET page that displays only those products in a specified category. 다음 예에서는 CategoryID 범주에 있는 모든 제품을 보여 줍니다. 여기서는 CategoryID 가 1입니다.The following example shows all products that are in the Beverages category, which have a CategoryID of 1.

음료 .aspBeverages.asp

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Beverages.aspx.cs"
    Inherits="Beverages" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
    <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h2>Beverages</h2>
        <p>
            <asp:GridView ID="GridView1" runat="server"
             CssClass="DataWebControlStyle">
               <HeaderStyle CssClass="HeaderStyle" />
               <AlternatingRowStyle CssClass="AlternatingRowStyle" />
            </asp:GridView>
             </p>
    </div>
    </form>
</body>
</html>

Beverages.aspx.csBeverages.aspx.cs

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using NorthwindTableAdapters;
public partial class Beverages : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        ProductsTableAdapter productsAdapter = new
         ProductsTableAdapter();
        GridView1.DataSource =
          productsAdapter.GetProductsByCategoryID(1);
        GridView1.DataBind();
    }
}

음료 범주의 제품이 표시 Those Products in the Beverages Category are Displayed

그림 20: 음료 범주의 제품이 표시 됩니다 (전체 크기 이미지를 보려면 클릭).Figure 20: Those Products in the Beverages Category are Displayed (Click to view full-size image)

4 단계: 데이터 삽입, 업데이트 및 삭제Step 4: Inserting, Updating, and Deleting Data

데이터를 삽입, 업데이트 및 삭제 하는 데 일반적으로 사용 되는 두 가지 패턴이 있습니다.There are two patterns commonly used for inserting, updating, and deleting data. 데이터베이스 직접 패턴을 호출 하는 첫 번째 패턴은 호출 될 때 단일 데이터베이스 레코드에 대해 작동 하는 데이터베이스에 INSERT, UPDATE또는 DELETE 명령을 실행 하는 메서드를 만드는 것입니다.The first pattern, which I'll call the database direct pattern, involves creating methods that, when invoked, issue an INSERT, UPDATE, or DELETE command to the database that operates on a single database record. 이러한 메서드는 일반적으로 삽입, 업데이트 또는 삭제할 값에 해당 하는 일련의 스칼라 값 (정수, 문자열, 부울, 날짜/시간 등)으로 전달 됩니다.Such methods are typically passed in a series of scalar values (integers, strings, Booleans, DateTimes, and so on) that correspond to the values to insert, update, or delete. 예를 들어 Products 테이블에 대해이 패턴을 사용 하면 delete 메서드가 정수 매개 변수를 사용 하 여 삭제할 레코드의 ProductID 를 표시 하는 반면 insert 메서드는 ProductName에 대 한 문자열, UnitPrice의 경우 decimal, UnitsOnStock에 대 한 정수를 사용 합니다.For example, with this pattern for the Products table the delete method would take in an integer parameter, indicating the ProductID of the record to delete, while the insert method would take in a string for the ProductName, a decimal for the UnitPrice, an integer for the UnitsOnStock, and so on.

각 삽입, 업데이트 및 삭제 요청 데이터베이스에 즉시 전송 됩니다.Each Insert, Update, and Delete Request is Sent to the Database Immediately

그림 21: 각 삽입, 업데이트 및 삭제 요청은 즉시 데이터베이스로 전송 됩니다 (전체 크기 이미지를 보려면 클릭).Figure 21: Each Insert, Update, and Delete Request is Sent to the Database Immediately (Click to view full-size image)

일괄 처리 업데이트 패턴으로 참조 하는 다른 패턴은 하나의 메서드 호출에서 전체 데이터 집합, DataTable 또는 Datarow의 컬렉션을 업데이트 하는 것입니다.The other pattern, which I'll refer to as the batch update pattern, is to update an entire DataSet, DataTable, or collection of DataRows in one method call. 개발자는이 패턴을 사용 하 여 DataTable에서 Datarow을 삭제, 삽입 및 수정한 다음 이러한 Datarow 또는 DataTable을 update 메서드로 전달 합니다.With this pattern a developer deletes, inserts, and modifies the DataRows in a DataTable and then passes those DataRows or DataTable into an update method. 그런 다음이 메서드는 전달 된 Datarow를 열거 하 고,이를 수정, 추가 또는 삭제 (DataRow의 RowState 속성 값을 통해) 하는지 여부를 확인 하 고 각 레코드에 대해 적절 한 데이터베이스 요청을 실행 합니다.This method then enumerates the DataRows passed in, determines whether or not they've been modified, added, or deleted (via the DataRow's RowState property value), and issues the appropriate database request for each record.

Update 메서드를 호출할 때 모든 변경 내용이 데이터베이스와 동기화 All Changes are Synchronized with the Database When the Update Method is Invoked

그림 22: 업데이트 메서드를 호출할 때 모든 변경 내용이 데이터베이스와 동기화 됨 (전체 크기 이미지를 보려면 클릭)Figure 22: All Changes are Synchronized with the Database When the Update Method is Invoked (Click to view full-size image)

TableAdapter는 기본적으로 batch 업데이트 패턴을 사용 하지만 DB 직접 패턴도 지원 합니다.The TableAdapter uses the batch update pattern by default, but also supports the DB direct pattern. TableAdapter를 만들 때 고급 속성에서 "Insert, Update 및 Delete 문 생성" 옵션을 선택 했으므로 제품 Stableadapter 는 batch 업데이트 패턴을 구현 하는 update () 메서드를 포함 합니다.Since we selected the "Generate Insert, Update, and Delete statements" option from the Advanced Properties when creating our TableAdapter, the ProductsTableAdapter contains an Update() method, which implements the batch update pattern. 특히 TableAdapter는 형식화 된 데이터 집합, 강력한 형식의 DataTable 또는 하나 이상의 Datarow를 전달할 수 있는 Update () 메서드를 포함 합니다.Specifically, the TableAdapter contains an Update() method that can be passed the Typed DataSet, a strongly-typed DataTable, or one or more DataRows. TableAdapter를 처음 만들 때 "GenerateDBDirectMethods" 확인란을 선택한 경우 DB 직접 패턴도 Insert () , Update ()Delete () 메서드를 통해 구현 됩니다.If you left the "GenerateDBDirectMethods" checkbox checked when first creating the TableAdapter the DB direct pattern will also be implemented via Insert(), Update(), and Delete() methods.

두 데이터 수정 패턴 모두 TableAdapter의 InsertCommand, UpdateCommandDeleteCommand 속성을 사용 하 여 데이터베이스에 대 한 삽입, 업데이트삭제 명령을 실행 합니다.Both data modification patterns use the TableAdapter's InsertCommand, UpdateCommand, and DeleteCommand properties to issue their INSERT, UPDATE, and DELETE commands to the database. 데이터 집합 디자이너에서 TableAdapter를 클릭 한 다음 속성 창로 이동 하 여 InsertCommand, UpdateCommandDeleteCommand 속성을 검사 하 고 수정할 수 있습니다.You can inspect and modify the InsertCommand, UpdateCommand, and DeleteCommand properties by clicking on the TableAdapter in the DataSet Designer and then going to the Properties window. (TableAdapter를 선택 했는지 확인 하 고, 제품의 드롭다운 목록에서 선택한 제품의 Stableadapter 개체가 속성 창.(Make sure you have selected the TableAdapter, and that the ProductsTableAdapter object is the one selected in the drop-down list in the Properties window.)

TableAdapter에 InsertCommand, UpdateCommand 및 DeleteCommand 속성이 있습니다.The TableAdapter has InsertCommand, UpdateCommand, and DeleteCommand Properties

그림 23: TableAdapter에 InsertCommand, UpdateCommandDeleteCommand 속성이 있음 (전체 크기 이미지를 보려면 클릭)Figure 23: The TableAdapter has InsertCommand, UpdateCommand, and DeleteCommand Properties (Click to view full-size image)

이러한 데이터베이스 명령 속성을 검토 하거나 수정 하려면 CommandText 하위 속성을 클릭 합니다. 그러면 쿼리 작성기이 표시 됩니다.To examine or modify any of these database command properties, click on the CommandText subproperty, which will bring up the Query Builder.

쿼리 작성기에서 INSERT, UPDATE 및 DELETE 문을 구성 합니다.Configure the INSERT, UPDATE, and DELETE Statements in the Query Builder

그림 24: 쿼리 작성기에서 삽입, 업데이트삭제 문 구성 (전체 크기 이미지를 보려면 클릭)Figure 24: Configure the INSERT, UPDATE, and DELETE Statements in the Query Builder (Click to view full-size image)

다음 코드 예제에서는 배치 업데이트 패턴을 사용 하 여 더 이상 지원 되지 않으며 재고 단위가 25 단위인 모든 제품의 가격을 두 배로 만드는 방법을 보여 줍니다.The following code example shows how to use the batch update pattern to double the price of all products that are not discontinued and that have 25 units in stock or less:

NorthwindTableAdapters.ProductsTableAdapter productsAdapter =
  new NorthwindTableAdapters.ProductsTableAdapter();
// For each product, double its price if it is not discontinued and
// there are 25 items in stock or less
Northwind.ProductsDataTable products = productsAdapter.GetProducts();
foreach (Northwind.ProductsRow product in products)
   if (!product.Discontinued && product.UnitsInStock <= 25)
      product.UnitPrice *= 2;
// Update the products
productsAdapter.Update(products);

아래 코드에서는 DB direct 패턴을 사용 하 여 프로그래밍 방식으로 특정 제품을 삭제 한 다음 업데이트 하 고 새 항목을 추가 하는 방법을 보여 줍니다.The code below illustrates how to use the DB direct pattern to programmatically delete a particular product, then update one, and then add a new one:

NorthwindTableAdapters.ProductsTableAdapter productsAdapter =
    new NorthwindTableAdapters.ProductsTableAdapter();
// Delete the product with ProductID 3
productsAdapter.Delete(3);
// Update Chai (ProductID of 1), setting the UnitsOnOrder to 15
productsAdapter.Update("Chai", 1, 1, "10 boxes x 20 bags",
  18.0m, 39, 15, 10, false, 1);
// Add a new product
productsAdapter.Insert("New Product", 1, 1,
  "12 tins per carton", 14.95m, 15, 0, 10, false);

사용자 지정 삽입, 업데이트 및 삭제 메서드 만들기Creating Custom Insert, Update, and Delete Methods

DB direct 메서드에서 만든 Insert () , Update ( ) 및 Delete () 메서드는 특히 많은 열이 있는 테이블의 경우 다소 복잡할 수 있습니다.The Insert(), Update(), and Delete() methods created by the DB direct method can be a bit cumbersome, especially for tables with many columns. IntelliSense의 도움 없이 이전 코드 예제를 살펴보면 Update ()Insert () 메서드의 각 입력 매개 변수에 매핑되는 제품 테이블 열이 명확 하지 않습니다.Looking at the previous code example, without IntelliSense's help it's not particularly clear what Products table column maps to each input parameter to the Update() and Insert() methods. 단일 열 또는 두 개의 열만 업데이트 하거나 새로 삽입 된 레코드의 id (자동 증가) 필드 값을 반환 하는 사용자 지정 된 Insert () 메서드를 원하는 경우도 있습니다.There may be times when we only want to update a single column or two, or want a customized Insert() method that will, perhaps, return the value of the newly inserted record's IDENTITY (auto-increment) field.

이러한 사용자 지정 메서드를 만들려면 데이터 집합 디자이너로 돌아갑니다.To create such a custom method, return to the DataSet Designer. TableAdapter를 마우스 오른쪽 단추로 클릭 하 고 쿼리 추가를 선택 하 여 TableAdapter 마법사로 돌아갑니다.Right-click on the TableAdapter and choose Add Query, returning to the TableAdapter wizard. 두 번째 화면에서 만들 쿼리 유형을 나타낼 수 있습니다.On the second screen we can indicate the type of query to create. 새 제품을 추가한 다음 새로 추가 된 레코드의 ProductID값을 반환 하는 메서드를 만들어 보겠습니다.Let's create a method that adds a new product and then returns the value of the newly added record's ProductID. 따라서 INSERT 쿼리를 만들도록 옵트인 합니다.Therefore, opt to create an INSERT query.

Products 테이블에 새 행을 추가 하는 메서드를 만드는 Create a Method to Add a New Row to the Products Table

그림 25: Products 테이블에 새 행을 추가 하는 메서드 만들기 (전체 크기 이미지를 보려면 클릭)Figure 25: Create a Method to Add a New Row to the Products Table (Click to view full-size image)

다음 화면에서 InsertCommandCommandText 가 표시 됩니다.On the next screen the InsertCommand's CommandText appears. 쿼리 끝에 SELECT SCOPE_identity () 를 추가 하 여이 쿼리를 보강 합니다. 그러면 동일한 범위의 id 열에 삽입 된 마지막 id 값이 반환 됩니다.Augment this query by adding SELECT SCOPE_IDENTITY() at the end of the query, which will return the last identity value inserted into an IDENTITY column in the same scope. ( ) 범위_identity () 에 대 한 자세한 내용 및 @@IDENTITY를 사용 하_IDENTITY () 범위를 사용 하려는 이유는 기술 설명서 를 참조 하십시오. SELECT 문을 추가 하기 전에 세미콜론을 사용 하 여 INSERT 문을 종료 했는지 확인 합니다.(See the technical documentation for more information about SCOPE_IDENTITY() and why you probably want to use SCOPE_IDENTITY() in lieu of @@IDENTITY.) Make sure that you end the INSERT statement with a semi-colon before adding the SELECT statement.

SCOPE_IDENTITY () 값을 반환 하도록 쿼리를 보강 Augment the Query to Return the SCOPE_IDENTITY() Value

그림 26: 범위_IDENTITY () 값을 반환 하도록 쿼리 보강 (전체 크기 이미지를 보려면 클릭)Figure 26: Augment the Query to Return the SCOPE_IDENTITY() Value (Click to view full-size image)

마지막으로 새 메서드 이름을 Insertproduct로 합니다.Finally, name the new method InsertProduct.

새 메서드 이름을 InsertProduct로 설정 Set the New Method Name to InsertProduct

그림 27: 새 메서드 이름을 insertproduct 로 설정 (전체 크기 이미지를 보려면 클릭)Figure 27: Set the New Method Name to InsertProduct (Click to view full-size image)

데이터 집합 디자이너로 돌아가면 상품 Stableadapter 에 새 메서드인 insertproduct가 포함 되어 있는 것을 볼 수 있습니다.When you return to the DataSet Designer you'll see that the ProductsTableAdapter contains a new method, InsertProduct. 이 새 메서드에 Products 테이블의 각 열에 대 한 매개 변수가 없는 경우에는 세미콜론으로 INSERT 문을 종료 하지 않아도 됩니다.If this new method doesn't have a parameter for each column in the Products table, chances are you forgot to terminate the INSERT statement with a semi-colon. Insertproduct 메서드를 구성 하 고 INSERTSELECT 문을 세미콜론으로 구분 하는지 확인 합니다.Configure the InsertProduct method and ensure you have a semi-colon delimiting the INSERT and SELECT statements.

기본적으로 insert 메서드는 쿼리가 아닌 메서드를 실행 하 여 영향을 받는 행의 수를 반환 합니다.By default, insert methods issue non-query methods, meaning that they return the number of affected rows. 그러나 Insertproduct 메서드는 영향을 받는 행 수가 아니라 쿼리에서 반환 된 값을 반환 하려고 합니다.However, we want the InsertProduct method to return the value returned by the query, not the number of rows affected. 이를 수행 하려면 Insertproduct 메서드의 Executemode 속성을 스칼라로 조정 합니다.To accomplish this, adjust the InsertProduct method's ExecuteMode property to Scalar.

ExecuteMode 속성을 스칼라로 변경 합니다.Change the ExecuteMode Property to Scalar

그림 28: Executemode 속성을 스칼라 로 변경 (전체 크기 이미지를 보려면 클릭)Figure 28: Change the ExecuteMode Property to Scalar (Click to view full-size image)

다음 코드에서는이 새 Insertproduct 메서드를 실행 하는 방법을 보여 줍니다.The following code shows this new InsertProduct method in action:

NorthwindTableAdapters.ProductsTableAdapter productsAdapter =
    new NorthwindTableAdapters.ProductsTableAdapter();
// Add a new product
int new_productID = Convert.ToInt32(productsAdapter.InsertProduct
    ("New Product", 1, 1, "12 tins per carton", 14.95m, 10, 0, 10, false));
// On second thought, delete the product
productsAdapter.Delete(new_productID);

5 단계: 데이터 액세스 계층 완료Step 5: Completing the Data Access Layer

Products stableststststststststststststststststststststststststststststststststststststststststststststststststststststststststststststststststableNote that the ProductsTableAdapters class returns the CategoryID and SupplierID values from the Products table, but doesn't include the CategoryName column from the Categories table or the CompanyName column from the Suppliers table, although these are likely the columns we want to display when showing product information. TableAdapter의 초기 메서드인 Getproducts () 를 확장 하 여 범주CompanyName 열 값을 모두 포함할 수 있습니다. 그러면 이러한 새 열도 포함 하도록 강력한 형식의 DataTable이 업데이트 됩니다.We can augment the TableAdapter's initial method, GetProducts(), to include both the CategoryName and CompanyName column values, which will update the strongly-typed DataTable to include these new columns as well.

그러나 데이터 삽입, 업데이트 및 삭제에 대 한 TableAdapter의 메서드는이 초기 방법을 기반으로 하기 때문에 문제를 일으킬 수 있습니다.This can present a problem, however, as the TableAdapter's methods for inserting, updating, and deleting data are based off of this initial method. 다행히 삽입, 업데이트 및 삭제를 위한 자동 생성 된 메서드는 SELECT 절의 하위 쿼리에서 영향을 받지 않습니다.Fortunately, the auto-generated methods for inserting, updating, and deleting are not affected by subqueries in the SELECT clause. 조인 대신 범주공급자 에 대 한 쿼리를 하위 쿼리로 추가 하면 데이터를 수정 하기 위해 이러한 메서드를 다시 사용 하지 않아도 됩니다.By taking care to add our queries to Categories and Suppliers as subqueries, rather than JOIN s, we'll avoid having to rework those methods for modifying data. Products Stableadapter 에서 getproducts () 메서드를 마우스 오른쪽 단추로 클릭 하 고 구성을 선택 합니다.Right-click on the GetProducts() method in the ProductsTableAdapter and choose Configure. 그런 다음 다음과 같이 SELECT 절을 조정 합니다.Then, adjust the SELECT clause so that it looks like:

SELECT     ProductID, ProductName, SupplierID, CategoryID,
QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued,
(SELECT CategoryName FROM Categories
WHERE Categories.CategoryID = Products.CategoryID) as CategoryName,
(SELECT CompanyName FROM Suppliers
WHERE Suppliers.SupplierID = Products.SupplierID) as SupplierName
FROM         Products

GetProducts () 메서드에 대 한 SELECT 문을 업데이트 Update the SELECT Statement for the GetProducts() Method

그림 29: getproducts () 메서드에 대 한 SELECT 문 업데이트 (전체 크기 이미지를 보려면 클릭)Figure 29: Update the SELECT Statement for the GetProducts() Method (Click to view full-size image)

Getproducts () 메서드를 업데이트 하 여이 새 쿼리를 사용 하면 DataTable에는 두 개의 새 열인 범주SupplierName포함 됩니다.After updating the GetProducts() method to use this new query the DataTable will include two new columns: CategoryName and SupplierName.

Products DataTable에는 두 개의 새 열이 있습니다.

그림 30: Products DataTable에 두 개의 새 열이 있습니다.Figure 30: The Products DataTable has Two New Columns

GetProductsByCategoryID (categoryID) 메서드에서 SELECT 절도 업데이트 합니다.Take a moment to update the SELECT clause in the GetProductsByCategoryID(categoryID) method as well.

Getproducts () 를 업데이트 하는 경우 조인 구문 사용을 선택 합니다. 데이터 집합 디자이너는 DB direct 패턴을 사용 하 여 데이터베이스 데이터를 삽입, 업데이트 및 삭제 하는 메서드를 자동 생성할 수 없습니다.If you update the GetProducts() SELECT using JOIN syntax the DataSet Designer won't be able to auto-generate the methods for inserting, updating, and deleting database data using the DB direct pattern. 대신이 자습서의 앞부분에서 Insertproduct 메서드를 사용 하는 것 처럼 수동으로 만들어야 합니다.Instead, you'll have to manually create them much like we did with the InsertProduct method earlier in this tutorial. 또한 일괄 업데이트 패턴을 사용 하려면 InsertCommand, UpdateCommandDeleteCommand 속성 값을 수동으로 제공 해야 합니다.Furthermore, you'll manually have to provide the InsertCommand, UpdateCommand, and DeleteCommand property values if you want to use the batch updating pattern.

나머지 Tableadapter 추가Adding the Remaining TableAdapters

지금까지 단일 TableAdapter를 단일 데이터베이스 테이블에 대 한 작업 으로만 살펴보았습니다.Up until now, we've only looked at working with a single TableAdapter for a single database table. 그러나 Northwind 데이터베이스에는 웹 응용 프로그램에서 사용 해야 하는 여러 관련 테이블이 포함 되어 있습니다.However, the Northwind database contains several related tables that we'll need to work with in our web application. 형식화 된 데이터 집합에는 관련 된 여러 Datatable 포함 될 수 있습니다.A Typed DataSet can contain multiple, related DataTables. 따라서 DAL을 완료 하려면 이러한 자습서에서 사용할 다른 테이블에 대 한 Datatable를 추가 해야 합니다.Therefore, to complete our DAL we need to add DataTables for the other tables we'll be using in these tutorials. 형식화 된 데이터 집합에 새 TableAdapter를 추가 하려면 데이터 집합 디자이너를 열고 디자이너를 마우스 오른쪽 단추로 클릭 한 다음 추가/TableAdapter를 선택 합니다.To add a new TableAdapter to a Typed DataSet, open the DataSet Designer, right-click in the Designer, and choose Add / TableAdapter. 그러면 새 DataTable 및 TableAdapter가 생성 되 고이 자습서의 앞부분에서 설명한 마법사를 안내 합니다.This will create a new DataTable and TableAdapter and walk you through the wizard we examined earlier in this tutorial.

다음 쿼리를 사용 하 여 다음 Tableadapter 및 메서드를 만드는 데 몇 분 정도 걸립니다.Take a few minutes to create the following TableAdapters and methods using the following queries. 상품 Stableadapter 의 쿼리에는 각 제품의 범주 및 공급자 이름을 가져오는 하위 쿼리가 포함 되어 있습니다.Note that the queries in the ProductsTableAdapter include the subqueries to grab each product's category and supplier names. 또한 함께 수행 하는 경우 제품 Stableadapter 클래스의 getproducts ()GetProductsByCategoryID (categoryID) 메서드를 이미 추가 했습니다.Additionally, if you've been following along, you've already added the ProductsTableAdapter class's GetProducts() and GetProductsByCategoryID(categoryID) methods.

  • 제품 StableadapterProductsTableAdapter

    • Getproducts:GetProducts:

      SELECT     ProductID, ProductName, SupplierID, 
      CategoryID, QuantityPerUnit, UnitPrice, UnitsInStock, 
      UnitsOnOrder, ReorderLevel, Discontinued, 
      (SELECT CategoryName FROM Categories WHERE
      Categories.CategoryID = Products.CategoryID) as 
      CategoryName, (SELECT CompanyName FROM Suppliers
      WHERE Suppliers.SupplierID = Products.SupplierID) 
      as SupplierName
      FROM         Products
      
    • GetProductsByCategoryID:GetProductsByCategoryID:

      SELECT     ProductID, ProductName, SupplierID, CategoryID,
      QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
      ReorderLevel, Discontinued, (SELECT CategoryName
      FROM Categories WHERE Categories.CategoryID = 
      Products.CategoryID) as CategoryName,
      (SELECT CompanyName FROM Suppliers WHERE
      Suppliers.SupplierID = Products.SupplierID)
      as SupplierName
      FROM         Products
      WHERE      CategoryID = @CategoryID
      
    • GetProductsBySupplierID:GetProductsBySupplierID:

      SELECT     ProductID, ProductName, SupplierID, CategoryID,
      QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
      ReorderLevel, Discontinued, (SELECT CategoryName
      FROM Categories WHERE Categories.CategoryID = 
      Products.CategoryID) as CategoryName, 
      (SELECT CompanyName FROM Suppliers WHERE 
      Suppliers.SupplierID = Products.SupplierID) as SupplierName
      FROM         Products
      WHERE SupplierID = @SupplierID
      
    • Getproductid byproductid:GetProductByProductID:

      SELECT     ProductID, ProductName, SupplierID, CategoryID,
      QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
      ReorderLevel, Discontinued, (SELECT CategoryName 
      FROM Categories WHERE Categories.CategoryID = 
      Products.CategoryID) as CategoryName, 
      (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID) 
      as SupplierName
      FROM         Products
      WHERE ProductID = @ProductID
      
  • CategoriesTableAdapterCategoriesTableAdapter

    • Getcategories:GetCategories:

      SELECT     CategoryID, CategoryName, Description
      FROM         Categories
      
    • Getcategorybycategoryid:GetCategoryByCategoryID:

      SELECT     CategoryID, CategoryName, Description
      FROM         Categories
      WHERE CategoryID = @CategoryID
      
  • SuppliersTableAdapterSuppliersTableAdapter

    • Getsuppliers:GetSuppliers:

      SELECT     SupplierID, CompanyName, Address,
      City, Country, Phone
      FROM         Suppliers
      
    • GetSuppliersByCountry:GetSuppliersByCountry:

      SELECT     SupplierID, CompanyName, Address,
      City, Country, Phone
      FROM         Suppliers
      WHERE Country = @Country
      
    • GetSupplierBySupplierID:GetSupplierBySupplierID:

      SELECT     SupplierID, CompanyName, Address,
      City, Country, Phone
      FROM         Suppliers
      WHERE SupplierID = @SupplierID
      
  • EmployeesTableAdapterEmployeesTableAdapter

    • GetEmployees:GetEmployees:

      SELECT     EmployeeID, LastName, FirstName, Title,
      HireDate, ReportsTo, Country
      FROM         Employees
      
    • GetEmployeesByManager:GetEmployeesByManager:

      SELECT     EmployeeID, LastName, FirstName, Title, 
      HireDate, ReportsTo, Country
      FROM         Employees
      WHERE ReportsTo = @ManagerID
      
    • GetEmployeeByEmployeeID:GetEmployeeByEmployeeID:

      SELECT     EmployeeID, LastName, FirstName, Title,
      HireDate, ReportsTo, Country
      FROM         Employees
      WHERE EmployeeID = @EmployeeID
      

4 개의 Tableadapter가 추가 된 후 데이터 집합 디자이너를 합니다.The DataSet Designer After the Four TableAdapters Have Been Added

그림 31: 네 개의 Tableadapter가 추가 된 후의 데이터 집합 디자이너 (전체 크기 이미지를 보려면 클릭)Figure 31: The DataSet Designer After the Four TableAdapters Have Been Added (Click to view full-size image)

DAL에 사용자 지정 코드 추가Adding Custom Code to the DAL

형식화 된 데이터 집합에 추가 된 Tableadapter 및 Datatable는 XML 스키마 정의 파일 (Northwind .xsd)로 표시 됩니다.The TableAdapters and DataTables added to the Typed DataSet are expressed as an XML Schema Definition file (Northwind.xsd). 솔루션 탐색기에서 Northwind .xsd 파일을 마우스 오른쪽 단추로 클릭 하 고 코드 보기를 선택 하 여이 스키마 정보를 볼 수 있습니다.You can view this schema information by right-clicking on the Northwind.xsd file in the Solution Explorer and choosing View Code.

Northwinds 형식화 된 데이터 집합에 대 한 XSD (XML 스키마 정의) 파일을 합니다.The XML Schema Definition (XSD) File for the Northwinds Typed DataSet

그림 32: Northwinds 형식화 된 데이터 집합에 대 한 XSD (XML 스키마 정의) 파일 (전체 크기 이미지를 보려면 클릭)Figure 32: The XML Schema Definition (XSD) File for the Northwinds Typed DataSet (Click to view full-size image)

이 스키마 정보는 런타임에 컴파일하거나 C# 런타임에 (필요한 경우) 실행 될 때 디자인 타임에 코드에서 또는 Visual Basic 코드로 변환 됩니다.This schema information is translated into C# or Visual Basic code at design time when compiled or at runtime (if needed), at which point you can step through it with the debugger. 자동 생성 된 코드를 보려면 클래스 뷰로 이동 하 고 TableAdapter 또는 형식화 된 데이터 집합 클래스로 드릴 다운 합니다.To view this auto-generated code go to the Class View and drill down to the TableAdapter or Typed DataSet classes. 화면에 클래스 뷰 표시 되지 않으면 보기 메뉴로 이동 하 여 여기에서 선택 하거나 Ctrl + Shift + C를 누릅니다.If you don't see the Class View on your screen, go to the View menu and select it from there, or hit Ctrl+Shift+C. 클래스 뷰에서 형식화 된 데이터 집합 및 TableAdapter 클래스의 속성, 메서드 및 이벤트를 볼 수 있습니다.From the Class View you can see the properties, methods, and events of the Typed DataSet and TableAdapter classes. 특정 메서드에 대 한 코드를 보려면 클래스 뷰에서 메서드 이름을 두 번 클릭 하거나 마우스 오른쪽 단추를 클릭 하 고 정의로 이동을 선택 합니다.To view the code for a particular method, double-click the method name in the Class View or right-click on it and choose Go To Definition.

클래스 뷰에서 정의로 이동을 선택 하 여 자동 생성 된 코드를 검사 합니다.

그림 33: 자동 생성 된 코드를 검사 하 여 클래스 뷰에서 정의로 이동을 선택 합니다.Figure 33: Inspect the Auto-Generated Code by Selecting Go To Definition from the Class View

자동 생성 된 코드는 상당한 시간 보호기가 될 수 있지만, 코드는 매우 일반적 이며 응용 프로그램의 고유한 요구 사항에 맞게 사용자 지정 해야 합니다.While auto-generated code can be a great time saver, the code is often very generic and needs to be customized to meet the unique needs of an application. 그러나 자동 생성 된 코드를 확장할 경우 코드를 생성 하는 도구에서 사용자 지정을 "다시 생성" 하 고 덮어쓸 때를 결정할 수 있습니다.The risk of extending auto-generated code, though, is that the tool that generated the code might decide it's time to "regenerate" and overwrite your customizations. .NET 2.0의 새로운 partial 클래스 개념을 사용 하 여 여러 파일 간에 클래스를 분할 하는 것이 쉽습니다.With .NET 2.0's new partial class concept, it's easy to split a class across multiple files. 이를 통해 Visual Studio에서 사용자 지정을 덮어쓰는 걱정 없이 자동 생성 된 클래스에 고유한 메서드, 속성 및 이벤트를 추가할 수 있습니다.This enables us to add our own methods, properties, and events to the auto-generated classes without having to worry about Visual Studio overwriting our customizations.

DAL을 사용자 지정 하는 방법을 보여 주기 위해 Getproducts () 메서드를 SuppliersRow 클래스에 추가 해 보겠습니다.To demonstrate how to customize the DAL, let's add a GetProducts() method to the SuppliersRow class. SuppliersRow 클래스는 Suppliers 테이블의 단일 레코드를 나타냅니다. 각 공급 업체는 0 개 이상의 제품을 공급자에 게 제공 하므로 Getproducts () 는 지정 된 공급자의 해당 제품을 반환 합니다.The SuppliersRow class represents a single record in the Suppliers table; each supplier can provider zero to many products, so GetProducts() will return those products of the specified supplier. 이 작업을 수행 하려면 SuppliersRow.cs 이라는 응용 프로그램_코드 폴더에 새 클래스 파일을 만들고 다음 코드를 추가 합니다.To accomplish this create a new class file in the App_Code folder named SuppliersRow.cs and add the following code:

using System;
using System.Data;
using NorthwindTableAdapters;
public partial class Northwind
{
    public partial class SuppliersRow
    {
        public Northwind.ProductsDataTable GetProducts()
        {
            ProductsTableAdapter productsAdapter =
             new ProductsTableAdapter();
            return
              productsAdapter.GetProductsBySupplierID(this.SupplierID);
        }
    }
}

이 partial 클래스는 방금 정의한 Getproducts () 메서드를 포함 하도록 SuppliersRow 클래스를 빌드할 때 컴파일러에 지시 합니다.This partial class instructs the compiler that when building the Northwind.SuppliersRow class to include the GetProducts() method we just defined. 프로젝트를 빌드한 후 클래스 뷰으로 돌아가면 이제 Getproducts ()SuppliersRow의 메서드로 나열 됩니다.If you build your project and then return to the Class View you'll see GetProducts() now listed as a method of Northwind.SuppliersRow.

GetProducts () 메서드는 이제 SuppliersRow 클래스의 일부입니다.

그림 34: getproducts () 메서드는 이제 SuppliersRow 클래스의 일부입니다 .Figure 34: The GetProducts() Method is Now Part of the Northwind.SuppliersRow Class

이제 다음 코드와 같이 Getproducts () 메서드를 사용 하 여 특정 공급자에 대 한 제품 집합을 열거할 수 있습니다.The GetProducts() method can now be used to enumerate the set of products for a particular supplier, as the following code shows:

NorthwindTableAdapters.SuppliersTableAdapter suppliersAdapter =
    new NorthwindTableAdapters.SuppliersTableAdapter();
// Get all of the suppliers
Northwind.SuppliersDataTable suppliers =
  suppliersAdapter.GetSuppliers();
// Enumerate the suppliers
foreach (Northwind.SuppliersRow supplier in suppliers)
{
    Response.Write("Supplier: " + supplier.CompanyName);
    Response.Write("<ul>");
    // List the products for this supplier
    Northwind.ProductsDataTable products = supplier.GetProducts();
    foreach (Northwind.ProductsRow product in products)
        Response.Write("<li>" + product.ProductName + "</li>");
    Response.Write("</ul><p> </p>");
}

이 데이터는 ASP에도 표시 될 수 있습니다. NET의 데이터 웹 컨트롤입니다.This data can also be displayed in any of ASP.NET's data Web controls. 다음 페이지에서는 두 개의 필드를 포함 하는 GridView 컨트롤을 사용 합니다.The following page uses a GridView control with two fields:

  • 각 공급자의 이름을 표시 하는 BoundFieldA BoundField that displays the name of each supplier, and
  • 각 공급자에 대해 Getproducts () 메서드가 반환 하는 결과에 바인딩된 BulletedList 컨트롤을 포함 하는 templatefield로 변환입니다.A TemplateField that contains a BulletedList control that is bound to the results returned by the GetProducts() method for each supplier.

이후 자습서에서 이러한 마스터-세부 보고서를 표시 하는 방법을 살펴보겠습니다.We'll examine how to display such master-detail reports in future tutorials. 지금은이 예제에서는 SuppliersRow 클래스에 추가 된 사용자 지정 메서드를 사용 하는 방법을 보여 주도록 디자인 되었습니다.For now, this example is designed to illustrate using the custom method added to the Northwind.SuppliersRow class.

SuppliersAndProducts.aspxSuppliersAndProducts.aspx

<%@ Page Language="C#" CodeFile="SuppliersAndProducts.aspx.cs"
    AutoEventWireup="true" Inherits="SuppliersAndProducts" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
    <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h2>
            Suppliers and Their Products</h2>
        <p>
            <asp:GridView ID="GridView1" runat="server"
             AutoGenerateColumns="False"
             CssClass="DataWebControlStyle">
                <HeaderStyle CssClass="HeaderStyle" />
                <AlternatingRowStyle CssClass="AlternatingRowStyle" />
                <Columns>
                    <asp:BoundField DataField="CompanyName"
                      HeaderText="Supplier" />
                    <asp:TemplateField HeaderText="Products">
                        <ItemTemplate>
                            <asp:BulletedList ID="BulletedList1"
                             runat="server" DataSource="<%# ((Northwind.SuppliersRow) ((System.Data.DataRowView) Container.DataItem).Row).GetProducts() %>"
                                 DataTextField="ProductName">
                            </asp:BulletedList>
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
             </p>
    </div>
    </form>
</body>
</html>

SuppliersAndProducts.aspx.csSuppliersAndProducts.aspx.cs

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using NorthwindTableAdapters;
public partial class SuppliersAndProducts : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        SuppliersTableAdapter suppliersAdapter = new
          SuppliersTableAdapter();
        GridView1.DataSource = suppliersAdapter.GetSuppliers();
        GridView1.DataBind();
    }
}

공급 업체의 회사 이름이 왼쪽 열에 표시 되 고 해당 제품을 오른쪽에 .The Supplier's Company Name is Listed in the Left Column, Their Products in the Right

그림 35: 공급자의 회사 이름이 왼쪽 열에 표시 되 고 해당 제품은 오른쪽에 표시 됩니다 (전체 크기 이미지를 보려면 클릭).Figure 35: The Supplier's Company Name is Listed in the Left Column, Their Products in the Right (Click to view full-size image)

요약Summary

웹 응용 프로그램을 빌드하는 경우 DAL을 만드는 첫 번째 단계 중 하나는 프레젠테이션 계층 만들기를 시작 하기 전에 발생 합니다.When building a web application creating the DAL should be one of your first steps, occurring before you start creating your presentation layer. Visual Studio를 사용 하 여 형식화 된 데이터 집합을 기반으로 DAL을 만드는 작업은 코드 줄을 작성 하지 않고도 10-15 분 내에 수행할 수 있는 작업입니다.With Visual Studio, creating a DAL based on Typed DataSets is a task that can be accomplished in 10-15 minutes without writing a line of code. 앞으로 이동 하는 자습서는이 DAL을 기반으로 빌드됩니다.The tutorials moving forward will build upon this DAL. 다음 자습서 에서는 여러 비즈니스 규칙을 정의 하 고 별도의 비즈니스 논리 계층에서 구현 하는 방법을 알아봅니다.In the next tutorial we'll define a number of business rules and see how to implement them in a separate Business Logic Layer.

행복 한 프로그래밍Happy Programming!

추가 참고 자료Further Reading

이 자습서에서 설명 하는 항목에 대 한 자세한 내용은 다음 리소스를 참조 하세요.For more information on the topics discussed in this tutorial, refer to the following resources:

이 자습서에 포함 된 항목에 대 한 비디오 학습Video Training on Topics Contained in this Tutorial

저자 정보About the Author

Scott Mitchell(7 개의 ASP/ASP. NET books 및 4GuysFromRolla.com창립자)은 1998부터 Microsoft 웹 기술을 사용 하 여 작업 했습니다.Scott Mitchell, author of seven ASP/ASP.NET books and founder of 4GuysFromRolla.com, has been working with Microsoft Web technologies since 1998. Scott은 독립 컨설턴트, 강사 및 기록기로 작동 합니다.Scott works as an independent consultant, trainer, and writer. 최신 책은 24 시간 이내에 ASP.NET 2.0을 sams teach yourself것입니다.His latest book is Sams Teach Yourself ASP.NET 2.0 in 24 Hours. mitchell@4GuysFromRolla.com에 도달할 수 있습니다 .He can be reached at mitchell@4GuysFromRolla.com. 또는 블로그를 통해 http://ScottOnWriting.NET에서 찾을 수 있습니다.or via his blog, which can be found at http://ScottOnWriting.NET.

특별히 감사 합니다.Special Thanks To

이 자습서 시리즈는 많은 유용한 검토자가 검토 했습니다.This tutorial series was reviewed by many helpful reviewers. 이 자습서에 대 한 잠재 고객 검토자는 녹색, Hilton Ron Esenow, Dennis Patterson이, Liz Shulok, Abel Gomez 및 Carlos Santos 였습니다.Lead reviewers for this tutorial were Ron Green, Hilton Giesenow, Dennis Patterson, Liz Shulok, Abel Gomez, and Carlos Santos. 예정 된 MSDN 문서를 검토 하는 데 관심이 있나요?Interested in reviewing my upcoming MSDN articles? 그렇다면mitchell@4GuysFromRolla.com에서 줄을 삭제 합니다.If so, drop me a line at mitchell@4GuysFromRolla.com.