다음을 통해 공유


JOIN을 사용하도록 TableAdapter 업데이트(C#)

작성자 : Scott Mitchell

PDF 다운로드

데이터베이스를 사용하는 경우 여러 테이블에 분산된 데이터를 요청하는 것이 일반적입니다. 서로 다른 두 테이블에서 데이터를 검색하려면 상관 관계가 있는 하위 쿼리 또는 JOIN 작업을 사용할 수 있습니다. 이 자습서에서는 기본 쿼리에 JOIN을 포함하는 TableAdapter를 만드는 방법을 살펴보기 전에 상호 관련된 하위 쿼리와 JOIN 구문을 비교합니다.

소개

관계형 데이터베이스를 사용하면 작업하는 데 관심이 있는 데이터가 여러 테이블에 분산되는 경우가 많습니다. 예를 들어 제품 정보를 표시할 때 각 제품의 해당 범주와 공급자 이름을 나열하려고 할 수 있습니다. Products 테이블에는 CategoryIDSupplierID 값이 있지만 실제 범주와 공급자 이름은 각각 및 Suppliers 테이블에 있습니다Categories.

다른 관련 테이블에서 정보를 검색하기 위해 상관 관계가 있는 하위 쿼리 또는 JOIN 사용할 수 있습니다. 상관 관계가 있는 하위 쿼리는 외부 쿼리의 열을 참조하는 중첩 SELECT 된 쿼리입니다. 예를 들어 데이터 액세스 계층 만들기 자습서에서는 기본 쿼리에서 ProductsTableAdapter 두 개의 상호 관련된 하위 쿼리를 사용하여 각 제품에 대한 범주 및 공급자 이름을 반환했습니다. 는 JOIN 서로 다른 두 테이블의 관련 행을 병합하는 SQL 구문입니다. SqlDataSource 컨트롤 자습서를 사용하여 데이터 쿼리 자습서에서 을 사용하여 JOIN 각 제품과 함께 범주 정보를 표시했습니다.

TableAdapters에서 s를 사용하지 JOIN 않도록 기권한 이유는 TableAdapter 마법사에서 해당 INSERT, UPDATEDELETE 문을 자동으로 생성하기 위한 제한 때문입니다. 특히 TableAdapter의 기본 쿼리에 s가 포함된 JOIN 경우 TableAdapter는 해당 , UpdateCommandDeleteCommand 속성에 대한 임시 SQL 문 또는 저장 프로시저를 InsertCommand자동으로 만들 수 없습니다.

이 자습서에서는 기본 쿼리에 를 포함하는 JOIN TableAdapter를 만드는 방법을 살펴보기 전에 상호 관련된 하위 쿼리와 를 간략하게 비교하고 JOIN 대조합니다.

상관 관계가 있는 하위 쿼리 및 s 비교 및JOIN 대비

ProductsTableAdapter DataSet의 첫 번째 자습서에서 Northwind 만든 는 상관 관계가 있는 하위 쿼리를 사용하여 각 제품의 해당 범주 및 공급자 이름을 다시 가져옵니다. ProductsTableAdapter 기본 쿼리는 다음과 같습니다.

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

상호 관련된 두 하위 쿼리 및 (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = Products.CategoryID)(SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID)SELECT 외부 문 열 목록의 추가 열로 제품당 단일 값을 반환하는 SELECT 쿼리입니다.

또는 을 JOIN 사용하여 각 제품의 공급업체 및 범주 이름을 반환할 수 있습니다. 다음 쿼리는 위의 출력과 동일한 출력을 반환하지만 하위 쿼리 대신 을 사용합니다 JOIN .

SELECT ProductID, ProductName, Products.SupplierID, Products.CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       Categories.CategoryName, 
       Suppliers.CompanyName as SupplierName
FROM Products
    LEFT JOIN Categories ON
        Categories.CategoryID = Products.CategoryID
    LEFT JOIN Suppliers ON
        Suppliers.SupplierID = Products.SupplierID

JOIN 일부 조건에 따라 한 테이블의 레코드를 다른 테이블의 레코드와 병합합니다. 예를 들어 위의 쿼리에서 는 LEFT JOIN Categories ON Categories.CategoryID = Products.CategoryID 값이 제품 CategoryID 값과 일치하는 범주 레코드와 각 제품 레코드 CategoryID 를 병합하도록 SQL Server 지시합니다. 병합된 결과를 사용하면 각 제품에 해당하는 범주 필드(예: )를 CategoryName사용할 수 있습니다.

참고

JOIN 는 일반적으로 관계형 데이터베이스의 데이터를 쿼리할 때 사용됩니다. 구문을 익숙하지 JOIN 않거나 사용 현황을 약간 정리해야 하는 경우 W3 SchoolsSQL 조인 자습서를 권장합니다. 또한 SQL 온라인 설명서JOIN 기본 사항하위 쿼리 기본 사항 섹션도 읽을 가치가 있습니다.

JOIN 의 하위 쿼리와 상관 관계가 있는 하위 쿼리를 모두 사용하여 다른 테이블에서 관련 데이터를 검색할 수 있으므로 많은 개발자가 머리를 긁적거리며 어떤 방법을 사용할지 궁금해합니다. 내가 이야기 한 모든 SQL 전문가는 거의 같은 일을 말했다, 그것은 정말 성능 면에서 중요하지 않습니다 SQL Server 거의 동일한 실행 계획을 생성합니다. 그런 다음, 그들의 조언은 사용자와 팀이 가장 편안하게 사용하는 기술을 사용하는 것입니다. 이 조언을 전한 후 이 전문가들은 상관 관계가 있는 하위 쿼리에 대한 선호도 JOIN 를 즉시 표현하는 것이 좋습니다.

형식화된 데이터 세트를 사용하여 데이터 액세스 계층을 빌드할 때 하위 쿼리를 사용할 때 도구가 더 잘 작동합니다. 특히 TableAdapter 마법사는 기본 쿼리에 s가 포함된 JOIN 경우 해당 INSERT, UPDATEDELETE 문을 자동으로 생성하지 않지만 상관 관계가 있는 하위 쿼리를 사용할 때 이러한 문을 자동으로 생성합니다.

이 단점을 살펴보려면 폴더에 임시 형식 데이터 세트를 ~/App_Code/DAL 만듭니다. TableAdapter 구성 마법사 중에 임시 SQL 문을 사용하도록 선택하고 다음 SELECT 쿼리를 입력합니다(그림 1 참조).

SELECT ProductID, ProductName, Products.SupplierID, Products.CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       Categories.CategoryName, 
       Suppliers.CompanyName as SupplierName
FROM Products
    LEFT JOIN Categories ON
        Categories.CategoryID = Products.CategoryID
    LEFT JOIN Suppliers ON
        Suppliers.SupplierID = Products.SupplierID

JON이 포함된 쿼리가 입력된 TableAdaptor 구성 마법사 창을 보여 주는 스크린샷

그림 1: 포함된 JOIN 기본 쿼리 입력(전체 크기 이미지를 보려면 클릭)

기본적으로 TableAdapter는 기본 쿼리에 따라 , UPDATEDELETE 문을 자동으로 만듭니INSERT다. 고급 단추를 클릭하면 이 기능이 활성화된 것을 볼 수 있습니다. 이 설정에도 불구하고 tableAdapter는 , 및 문을 만들 INSERT수 없습니다. 기본 쿼리에 가 포함되어 있기 때문입니다JOIN.DELETEUPDATE

삽입, 업데이트 및 삭제 문 생성 확인란이 선택된 고급 옵션 창을 보여 주는 스크린샷

그림 2: 를 포함하는 JOIN 기본 쿼리 입력

마침을 클릭하여 마법사를 완료합니다. 이 시점에서 DataSet의 Designer 쿼리 열 목록에 반환된 각 필드에 대한 열이 있는 DataTable이 있는 단일 TableAdapter를 SELECT 포함합니다. 여기에는 그림 3과 CategoryName 같이 및 SupplierName가 포함됩니다.

DataTable에는 열 목록에 반환된 각 필드에 대한 열이 포함됩니다.

그림 3: DataTable에는 열 목록에 반환된 각 필드에 대한 열이 포함됩니다.

DataTable에는 적절한 열이 있지만 TableAdapter에는 , UpdateCommandDeleteCommand 속성에 대한 값이 InsertCommand없습니다. 이를 확인하려면 Designer TableAdapter를 클릭한 다음 속성 창 이동합니다. 거기서 , UpdateCommandDeleteCommand 속성이 InsertCommand(없음) 로 설정된 것을 볼 수 있습니다.

InsertCommand, UpdateCommand 및 DeleteCommand 속성이 로 설정됨(없음)

그림 4: , UpdateCommandDeleteCommand 속성이 InsertCommand(없음)으로 설정됨(전체 크기 이미지를 보려면 클릭)

이 단점을 해결하기 위해 속성 창 통해 , UpdateCommand및 속성에 대한 InsertCommandSQL 문 및 DeleteCommand 매개 변수를 수동으로 제공할 수 있습니다. 또는 먼저 TableAdapter의 기본 쿼리를 구성하여 를 포함하지 않을 수 있습니다JOIN. 이렇게 하면 INSERT, UPDATEDELETE 문이 자동으로 생성될 수 있습니다. 마법사를 완료한 후 구문을 포함할 수 있도록 속성 창 TableAdapter s SelectCommandJOIN 수동으로 업데이트할 수 있습니다.

이 방법은 작동하지만 임시 SQL 쿼리를 사용할 때는 TableAdapter의 기본 쿼리가 마법사를 통해 다시 구성될 때마다 자동 생성된 , UPDATEDELETE 문이 다시 생성INSERT되기 때문에 매우 취약합니다. 즉, TableAdapter를 마우스 오른쪽 단추로 클릭하고 상황에 맞는 메뉴에서 구성을 선택한 다음 마법사를 다시 완료하면 나중에 만든 모든 사용자 지정이 손실됩니다.

TableAdapter의 자동 생성 INSERT, UPDATEDELETE 문의 취약성은 다행히 임시 SQL 문으로 제한됩니다. TableAdapter에서 저장 프로시저를 사용하는 경우 저장 프로시저가 수정될 것을 두려워하지 않고 , InsertCommand, UpdateCommand또는 DeleteCommand 저장 프로시저를 사용자 지정SelectCommand하고 TableAdapter 구성 마법사를 다시 실행할 수 있습니다.

다음 몇 단계를 통해 처음에는 해당 삽입, 업데이트 및 삭제 저장 프로시저가 자동으로 생성되도록 을 생략 JOIN 하는 기본 쿼리를 사용하는 TableAdapter를 만듭니다. 그런 다음 관련 테이블에서 추가 열을 반환하는 를 JOIN 사용할 수 있도록 을 업데이트 SelectCommand 합니다. 마지막으로 해당 비즈니스 논리 계층 클래스를 만들고 ASP.NET 웹 페이지에서 TableAdapter를 사용하는 방법을 보여 줍니다.

1단계: 간소화된 기본 쿼리를 사용하여 TableAdapter 만들기

이 자습서에서는 DataSet의 테이블에 대한 TableAdapter 및 강력한 형식의 Employees DataTable을 NorthwindWithSprocs 추가합니다. 테이블에는 EmployeesReportsTo 직원 관리자의 를 지정하는 EmployeeID 필드가 포함되어 있습니다. 예를 들어 직원 앤 도즈워스의 값은 ReportTo 5이며, 이는 스티븐 뷰캐넌의 값입니다 EmployeeID . 결과적으로 앤은 매니저 스티븐에게 보고합니다. 각 직원의 ReportsTo 가치를 보고하는 것 외에도 관리자의 이름을 검색할 수도 있습니다. 이 작업은 를 사용하여 JOIN수행할 수 있습니다. 그러나 처음에 TableAdapter를 만들 때 를 사용하면 JOIN 마법사가 해당 삽입, 업데이트 및 삭제 기능을 자동으로 생성하지 못하게 합니다. 따라서 먼저 기본 쿼리에 가 포함되지 JOIN 않은 TableAdapter를 만듭니다. 그런 다음, 2단계에서 기본 쿼리 저장 프로시저를 업데이트하여 를 통해 JOIN관리자 이름을 검색합니다.

먼저 폴더에서 NorthwindWithSprocs DataSet을 ~/App_Code/DAL 엽니다. Designer 마우스 오른쪽 단추로 클릭하고 상황에 맞는 메뉴에서 추가 옵션을 선택한 다음 TableAdapter 메뉴 항목을 선택합니다. 그러면 TableAdapter 구성 마법사가 시작됩니다. 그림 5와 같이 마법사에서 새 저장 프로시저를 만들고 다음을 클릭합니다. TableAdapter 마법사에서 새 저장 프로시저를 만드는 방법에 대한 새로 고침은 Typed DataSet의 TableAdapters 자습서에 대한 새 저장 프로시저 만들기 자습서를 참조하세요 .

새 저장 프로시저 만들기 옵션을 선택합니다.

그림 5: 새 저장 프로시저 만들기 옵션을 선택합니다(전체 크기 이미지를 보려면 클릭).

TableAdapter의 기본 쿼리에 다음 SELECT 문을 사용합니다.

SELECT EmployeeID, LastName, FirstName, Title, HireDate, ReportsTo, Country
FROM Employees

이 쿼리에는 가 포함되지 JOIN 않으므로 TableAdapter 마법사는 해당 INSERT, UPDATE및 문을 사용하여 저장 프로시저와 DELETE 기본 쿼리를 실행하기 위한 저장 프로시저를 자동으로 만듭니다.

다음 단계에서는 TableAdapter의 저장 프로시저 이름을 지정할 수 있습니다. 그림 6과 같이 이름 Employees_Select, Employees_InsertEmployees_Update, 및 Employees_Delete를 사용합니다.

TableAdapter의 저장 프로시저 이름 지정

그림 6: TableAdapter의 저장 프로시저 이름 지정(전체 크기 이미지를 보려면 클릭)

마지막 단계에서는 TableAdapter의 메서드 이름을 지정하라는 메시지를 표시합니다. 및 GetEmployees 를 메서드 이름으로 사용합니다Fill. 또한 데이터베이스에 직접 업데이트를 보내는 메서드 만들기(GenerateDBDirectMethods) 확인란을 선택해야 합니다.

TableAdapter의 메서드 채우기 및 GetEmployees 이름을 지정합니다.

그림 7: TableAdapter의 메서드 Fill 이름을 지정하고 GetEmployees (전체 크기 이미지를 보려면 클릭)

마법사를 완료한 후 잠시 시간을 내어 데이터베이스의 저장 프로시저를 검사합니다. , , 및 의 네 가지 Employees_Select새 항목이 Employees_Update표시됩니다.Employees_DeleteEmployees_Insert 다음으로, 를 검사하고 EmployeesDataTableEmployeesTableAdapter 방금 만들었습니다. DataTable에는 기본 쿼리에서 반환된 각 필드에 대한 열이 포함되어 있습니다. TableAdapter를 클릭한 다음 속성 창 이동합니다. 그러면 , UpdateCommandDeleteCommand 속성이 InsertCommand해당 저장 프로시저를 호출하도록 올바르게 구성된 것을 볼 수 있습니다.

TableAdapter에는 삽입, 업데이트 및 삭제 기능이 포함됩니다.

그림 8: TableAdapter에 삽입, 업데이트 및 삭제 기능이 포함되어 있습니다(전체 크기 이미지를 보려면 클릭).

저장 프로시저 삽입, 업데이트 및 삭제가 자동으로 생성되고 InsertCommand, UpdateCommandDeleteCommand 속성이 올바르게 구성되면 각 직원 관리자에 대한 추가 정보를 반환하도록 저장 프로시저를 사용자 지정할 SelectCommand 준비가 된 것입니다. 특히 를 사용하고 JOIN 관리자 FirstNameLastName 값을 반환하도록 저장 프로시저를 업데이트 Employees_Select 해야 합니다. 저장 프로시저가 업데이트된 후 이러한 추가 열을 포함하도록 DataTable을 업데이트해야 합니다. 2단계와 3단계에서 이 두 가지 작업을 다루겠습니다.

2단계: 를 포함하도록 저장 프로시저 사용자 지정JOIN

먼저 서버 Explorer 이동하여 Northwind 데이터베이스의 저장 프로시저 폴더로 드릴다운하고 저장 프로시저를 Employees_Select 엽니다. 이 저장 프로시저가 표시되지 않으면 저장 프로시저 폴더를 마우스 오른쪽 단추로 클릭하고 새로 고침을 선택합니다. 를 사용하여 LEFT JOIN 관리자의 이름과 성을 반환하도록 저장 프로시저를 업데이트합니다.

SELECT Employees.EmployeeID, Employees.LastName, 
       Employees.FirstName, Employees.Title, 
       Employees.HireDate, Employees.ReportsTo, 
       Employees.Country,
       Manager.FirstName as ManagerFirstName, 
       Manager.LastName as ManagerLastName
FROM Employees
    LEFT JOIN Employees AS Manager ON
        Employees.ReportsTo = Manager.EmployeeID

문을 업데이트한 SELECT 후 파일 메뉴로 이동하여 저장을 선택하여 변경 내용을 저장 Employees_Select합니다. 또는 도구 모음에서 저장 아이콘을 클릭하거나 Ctrl+S를 누를 수 있습니다. 변경 내용을 저장한 후 서버 Explorer 저장 프로시저를 마우스 오른쪽 단추로 클릭하고 Employees_Select 실행을 선택합니다. 그러면 저장 프로시저가 실행되고 출력 창에 결과가 표시됩니다(그림 9 참조).

저장 프로시저 결과가 출력 창에 표시됩니다.

그림 9: 저장 프로시저 결과가 출력 창에 표시됩니다(전체 크기 이미지를 보려면 클릭).

3단계: DataTable의 열 업데이트

이 시점에서 저장 프로시저는 Employees_SelectManagerLastName 값을 반환 ManagerFirstName 하지만 EmployeesDataTable 에는 이러한 열이 없습니다. 이러한 누락된 열은 다음 두 가지 방법 중 하나로 DataTable에 추가할 수 있습니다.

  • 수동으로 - DataSet Designer DataTable을 마우스 오른쪽 단추로 클릭하고 추가 메뉴에서 열을 선택합니다. 그런 다음 열의 이름을 지정하고 그에 따라 해당 속성을 설정할 수 있습니다.
  • 자동으로 - TableAdapter 구성 마법사는 저장 프로시저에서 반환된 SelectCommand 필드를 반영하도록 DataTable의 열을 업데이트합니다. 임시 SQL 문을 사용하는 경우 마법사는 , 및 속성도 제거합니다. 이제 에 가 포함되어 있기 때문에 마법사는 , 및 속성도 제거InsertCommand합니다JOIN.SelectCommandDeleteCommandUpdateCommand 그러나 저장 프로시저를 사용하는 경우 이러한 명령 속성은 그대로 유지됩니다.

세부 정보 데이터 목록과 함께 마스터 레코드의 글머리 기호 목록을 사용하는 마스터/세부 정보 사용파일 업로드를 포함하여 이전 자습서에서 DataTable 열을 수동으로 추가하는 방법을 살펴보았습니다. 다음 자습서에서는 이 프로세스를 다시 자세히 살펴보겠습니다. 그러나 이 자습서에서는 TableAdapter 구성 마법사를 통해 자동 접근 방식을 사용하겠습니다.

를 마우스 오른쪽 단추로 클릭하고 EmployeesTableAdapter 상황에 맞는 메뉴에서 구성을 선택하여 시작합니다. 그러면 반환 값 및 매개 변수(있는 경우)와 함께 선택, 삽입, 업데이트 및 삭제에 사용되는 저장 프로시저가 나열되는 TableAdapter 구성 마법사가 표시됩니다. 그림 10에서는 이 마법사를 보여줍니다. 여기서 저장 프로시저가 Employees_Select 이제 및 ManagerLastName 필드를 반환하는 ManagerFirstName 것을 볼 수 있습니다.

마법사에서 Employees_Select 저장 프로시저에 대한 업데이트된 열 목록을 표시합니다.

그림 10: 마법사에 저장 프로시저에 대한 Employees_Select 업데이트된 열 목록이 표시됩니다(전체 크기 이미지를 보려면 클릭).

마침을 클릭하여 마법사를 완료합니다. DataSet Designer EmployeesDataTable 돌아오면 에는 및 ManagerLastName의 두 개의 추가 열이 ManagerFirstName 포함됩니다.

EmployeesDataTable에는 두 개의 새 열이 포함되어 있습니다.

그림 11: 에는 EmployeesDataTable 두 개의 새 열이 포함되어 있습니다(전체 크기 이미지를 보려면 클릭).

업데이트 Employees_Select 된 저장 프로시저가 적용되고 TableAdapter의 삽입, 업데이트 및 삭제 기능이 여전히 작동한다는 것을 설명하기 위해 사용자가 직원을 보고 삭제할 수 있는 웹 페이지를 만들어 보겠습니다. 그러나 이러한 페이지를 만들기 전에 먼저 DataSet의 직원과 함께 작업하기 위해 비즈니스 논리 계층에 새 클래스를 NorthwindWithSprocs 만들어야 합니다. 4단계에서는 클래스를 만듭니다 EmployeesBLLWithSprocs . 5단계에서는 ASP.NET 페이지에서 이 클래스를 사용합니다.

4단계: 비즈니스 논리 계층 구현

라는 EmployeesBLLWithSprocs.cs폴더에 ~/App_Code/BLL 새 클래스 파일을 만듭니다. 이 클래스는 기존 EmployeesBLL 클래스의 의미 체계를 모방하며, 이 새 클래스만 더 적은 수의 메서드를 제공하고 DataSet 대신 DataSet를 Northwind 사용합니다NorthwindWithSprocs. EmployeesBLLWithSprocs 클래스에 다음 코드를 추가합니다.

using System;
using System.Data;
using System.Configuration;
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 NorthwindWithSprocsTableAdapters;
[System.ComponentModel.DataObject]
public class EmployeesBLLWithSprocs
{
    private EmployeesTableAdapter _employeesAdapter = null;
    protected EmployeesTableAdapter Adapter
    {
        get
        {
            if (_employeesAdapter == null)
                _employeesAdapter = new EmployeesTableAdapter();
            return _employeesAdapter;
        }
    }
    [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Select, true)]
    public NorthwindWithSprocs.EmployeesDataTable GetEmployees()
    {
        return Adapter.GetEmployees();
    }
    [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Delete, true)]
    public bool DeleteEmployee(int employeeID)
    {
        int rowsAffected = Adapter.Delete(employeeID);
        // Return true if precisely one row was deleted, otherwise false
        return rowsAffected == 1;
    }
}

클래스의 속성은 EmployeesBLLWithSprocs DataSet 의 NorthwindWithSprocs instance 반환합니다EmployeesTableAdapter.Adapter 이는 클래스 s GetEmployeesDeleteEmployee 메서드에서 사용됩니다. 메서드는 GetEmployees 저장 프로시저를 EmployeesTableAdapterGetEmployees 호출 Employees_Select 하고 결과를 에 채우는 해당 메서드를 EmployeeDataTable호출합니다. 메서드는 DeleteEmployee 마찬가지로 저장 프로시저를 EmployeesTableAdapter 호출하는 s Delete 메서드를 Employees_Delete 호출합니다.

5단계: 프레젠테이션 계층의 데이터 작업

수업이 EmployeesBLLWithSprocs 완료되면 ASP.NET 페이지를 통해 직원 데이터로 작업할 준비가 된 것입니다. 폴더에서 JOINs.aspxAdvancedDAL 페이지를 열고 Toolbox에서 Designer GridView를 끌어 속성을 IDEmployees로 설정합니다. 그런 다음 GridView의 스마트 태그에서 라는 새 ObjectDataSource 컨트롤 EmployeesDataSource에 그리드를 바인딩합니다.

클래스를 사용하도록 ObjectDataSource를 EmployeesBLLWithSprocs 구성하고 SELECT 및 DELETE 탭에서 드롭다운 목록에서 및 DeleteEmployee 메서드가 선택되어 있는지 확인 GetEmployees 합니다. 마침을 클릭하여 ObjectDataSource의 구성을 완료합니다.

EmployeesBLLWithSprocs 클래스를 사용하도록 ObjectDataSource 구성

그림 12: 클래스를 사용하도록 EmployeesBLLWithSprocs ObjectDataSource 구성(전체 크기 이미지를 보려면 클릭)

ObjectDataSource GetEmployees 및 DeleteEmployee 메서드 사용

그림 13: ObjectDataSource에서 및 DeleteEmployee 메서드를 GetEmployees 사용하도록 합니다(전체 크기 이미지를 보려면 클릭).

Visual Studio는 각 열에 대해 GridView에 BoundField를 EmployeesDataTable 추가합니다. , , LastName, ManagerLastNameFirstNameManagerFirstName및 를 제외한 Title이러한 BoundFields를 모두 제거하고 마지막 4개의 BoundFields 속성 이름을 각각 성, 이름, 관리자 이름 및 관리자의 성으로 바꿉 HeaderText 니다.

사용자가 이 페이지에서 직원을 삭제할 수 있도록 하려면 두 가지 작업을 수행해야 합니다. 먼저 스마트 태그에서 삭제 사용 옵션을 선택하여 삭제 기능을 제공하도록 GridView에 지시합니다. 둘째, ObjectDataSource 마법사()에서 설정한 값에서 ObjectDataSource의 OldValuesParameterFormatString 속성을 기본값(original_{0}{0})으로 변경합니다. 이러한 변경 후 GridView 및 ObjectDataSource의 선언적 태그는 다음과 유사하게 표시됩니다.

<asp:GridView ID="Employees" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="EmployeeID" DataSourceID="EmployeesDataSource">
    <Columns>
        <asp:CommandField ShowDeleteButton="True" />
        <asp:BoundField DataField="Title" 
            HeaderText="Title" 
            SortExpression="Title" />
        <asp:BoundField DataField="LastName" 
            HeaderText="Last Name" 
            SortExpression="LastName" />
        <asp:BoundField DataField="FirstName" 
            HeaderText="First Name" 
            SortExpression="FirstName" />
        <asp:BoundField DataField="ManagerFirstName" 
            HeaderText="Manager's First Name" 
            SortExpression="ManagerFirstName" />
        <asp:BoundField DataField="ManagerLastName" 
            HeaderText="Manager's Last Name" 
            SortExpression="ManagerLastName" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="EmployeesDataSource" runat="server" 
    DeleteMethod="DeleteEmployee" OldValuesParameterFormatString="{0}" 
    SelectMethod="GetEmployees" TypeName="EmployeesBLLWithSprocs">
    <DeleteParameters>
        <asp:Parameter Name="employeeID" Type="Int32" />
    </DeleteParameters>
</asp:ObjectDataSource>

브라우저를 통해 페이지를 방문하여 테스트합니다. 그림 14와 같이 페이지에는 각 직원과 관리자의 이름이 나열됩니다(해당 직원이 있다고 가정).

Employees_Select 저장 프로시저의 JOIN은 관리자 이름을 반환합니다.

그림 14: 저장 프로시저의 Employees_SelectJOIN 관리자 이름을 반환합니다(전체 크기 이미지를 보려면 클릭).

삭제 단추를 클릭하면 삭제 워크플로가 시작되어 저장 프로시저가 Employees_Delete 실행됩니다. 그러나 외래 키 제약 조건 위반으로 인해 저장 프로시저에서 시도된 DELETE 문이 실패합니다(그림 15 참조). 특히 각 직원에게는 테이블에 하나 이상의 레코드가 Orders 있으므로 삭제가 실패합니다.

해당 주문이 있는 직원을 삭제하면 외래 키 제약 조건 위반이 발생합니다.

그림 15: 해당 주문이 있는 직원을 삭제하면 외래 키 제약 조건 위반이 발생합니다(전체 크기 이미지를 보려면 클릭).

직원을 삭제할 수 있도록 하려면 다음을 수행할 수 있습니다.

나는 이것을 독자를위한 운동으로 남겨 둡니다.

요약

관계형 데이터베이스를 사용하는 경우 쿼리가 여러 관련 테이블에서 데이터를 가져오는 것이 일반적입니다. 상호 관련된 하위 쿼리 및 JOIN 는 쿼리의 관련 테이블에서 데이터에 액세스하기 위한 두 가지 기술을 제공합니다. 이전 자습서에서는 TableAdapter가 와 관련된 쿼리에 대해 , UPDATEDELETE 문을 자동으로 생성INSERT할 수 없으므로 가장 일반적으로 상관 관계가 있는 하위 쿼리를 JOIN 사용했습니다. 이러한 값을 수동으로 제공할 수 있지만 임시 SQL 문을 사용하는 경우 TableAdapter 구성 마법사가 완료되면 사용자 지정을 덮어씁니다.

다행히 저장 프로시저를 사용하여 만든 TableAdapters는 임시 SQL 문을 사용하여 만든 것과 동일한 취약성을 겪지 않습니다. 따라서 저장 프로시저를 사용할 때 기본 쿼리에서 를 사용하는 TableAdapter를 JOIN 만들 수 있습니다. 이 자습서에서는 이러한 TableAdapter를 만드는 방법을 알아보았습니다. 먼저 TableAdapter의 기본 쿼리에 대해 -less SELECT 쿼리를 사용하여 JOIN해당 삽입, 업데이트 및 삭제 저장 프로시저를 자동으로 만듭니다. TableAdapter의 초기 구성이 완료되면 를 사용하도록 JOIN 저장 프로시저를 보강 SelectCommand 하고 TableAdapter 구성 마법사를 다시 실행하여 열을 업데이트 EmployeesDataTable 했습니다.

TableAdapter 구성 마법사를 다시 실행하면 저장 프로시저에서 EmployeesDataTable 반환된 데이터 필드가 반영되도록 열이 Employees_Select 자동으로 업데이트되었습니다. 또는 이러한 열을 DataTable에 수동으로 추가할 수 있습니다. 다음 자습서에서는 DataTable에 열을 수동으로 추가하는 방법을 살펴봅니다.

행복한 프로그래밍!

저자 정보

7개의 ASP/ASP.NET 책의 저자이자 4GuysFromRolla.com 창립자인 Scott Mitchell은 1998년부터 Microsoft 웹 기술로 작업해 왔습니다. Scott은 독립 컨설턴트, 트레이너 및 작가로 일합니다. 그의 최신 책은 샘스 티치 유어셀프 ASP.NET 24시간 만에 2.0입니다. 그는 에서mitchell@4GuysFromRolla.com 또는 에서 찾을 http://ScottOnWriting.NET수있는 자신의 블로그를 통해 도달 할 수 있습니다.

특별 감사

이 자습서 시리즈는 많은 유용한 검토자가 검토했습니다. 이 자습서의 수석 검토자는 힐튼 가이세나우, 데이비드 수루, 테레사 머피였습니다. 예정된 MSDN 문서를 검토하는 데 관심이 있으신가요? 그렇다면 에 줄을 놓습니다 mitchell@4GuysFromRolla.com.