ASP.NET 웹 페이지(Razor) 사이트에서 데이터베이스 작업 소개

Tom FitzMacken

이 문서에서는 Microsoft WebMatrix 도구를 사용하여 ASP.NET 웹 페이지(Razor) 웹 사이트에서 데이터베이스를 만드는 방법과 데이터를 표시, 추가, 편집 및 삭제할 수 있는 페이지를 만드는 방법을 설명합니다.

학습할 내용:

  • 데이터베이스를 만드는 방법
  • 데이터베이스에 연결하는 방법
  • 웹 페이지에 데이터를 표시하는 방법
  • 데이터베이스 레코드를 삽입, 업데이트 및 삭제하는 방법입니다.

다음은 문서에 도입된 기능입니다.

  • Microsoft SQL Server Compact Edition 데이터베이스 작업
  • SQL 쿼리 작업.
  • Database 클래스

자습서에서 사용되는 소프트웨어 버전

  • ASP.NET 웹 페이지(Razor) 2
  • WebMatrix 2

이 자습서는 WebMatrix 3에서도 작동합니다. ASP.NET 웹 페이지 3 및 Visual Studio 2013(또는 웹용 Visual Studio Express 2013)을 사용할 수 있지만 사용자 인터페이스는 다릅니다.

데이터베이스 소개

일반적인 주소록을 상상해 보십시오. 주소록의 각 항목(즉, 각 사용자에 대해)에 이름, 성, 주소, 전자 메일 주소 및 전화 번호와 같은 몇 가지 정보가 있습니다.

이와 같은 데이터를 그리는 일반적인 방법은 행과 열이 있는 테이블입니다. 데이터베이스 측면에서 각 행을 레코드라고도 합니다. 각 열(필드라고도 함)에는 각 데이터 형식에 대한 값(이름, 성 등)이 포함됩니다.

ID FirstName LastName 주소 Email 전화
1 Jim 아브루스 () 210 100th St SE Orcas WA 98031 jim@contoso.com 555 0100
2 Terry Adams 1234 Main St. Seattle WA 99011 terry@cohowinery.com 555 0101

대부분의 데이터베이스 테이블의 경우 테이블에는 고객 번호, 계정 번호 등과 같은 고유 식별자가 포함된 열이 있어야 합니다. 이를 테이블의 기본 키라고 하며 이를 사용하여 테이블의 각 행을 식별합니다. 이 예제에서 ID 열은 주소록의 기본 키입니다.

데이터베이스에 대한 기본적인 이해를 통해 간단한 데이터베이스를 만들고 데이터 추가, 수정 및 삭제와 같은 작업을 수행하는 방법을 알아볼 준비가 된 것입니다.

관계형 데이터베이스

텍스트 파일 및 스프레드시트를 비롯한 다양한 방법으로 데이터를 저장할 수 있습니다. 하지만 대부분의 비즈니스 용도에서 데이터는 관계형 데이터베이스에 저장됩니다.

이 문서는 데이터베이스에 자세히 설명되지 않습니다. 그러나 이에 대해 조금 이해하는 것이 유용할 수 있습니다. 관계형 데이터베이스에서 정보는 논리적으로 별도의 테이블로 나뉩니다. 예를 들어 학교의 데이터베이스에는 학생 및 수업 제공에 대한 별도의 테이블이 포함될 수 있습니다. 데이터베이스 소프트웨어(예: SQL Server)는 테이블 간의 관계를 동적으로 설정할 수 있는 강력한 명령을 지원합니다. 예를 들어 관계형 데이터베이스를 사용하여 일정을 만들기 위해 학생과 수업 간에 논리적 관계를 설정할 수 있습니다. 별도의 테이블에 데이터를 저장하면 테이블 구조의 복잡성이 줄어들고 중복 데이터를 테이블에 유지할 필요가 줄어듭니다.

데이터베이스 만들기

이 절차에서는 WebMatrix에 포함된 SQL Server Compact 데이터베이스 디자인 도구를 사용하여 SmallBakery라는 데이터베이스를 만드는 방법을 보여줍니다. 코드를 사용하여 데이터베이스를 만들 수 있지만 WebMatrix와 같은 디자인 도구를 사용하여 데이터베이스 및 데이터베이스 테이블을 만드는 것이 더 일반적입니다.

  1. WebMatrix를 시작하고 빠른 시작 페이지에서 서식 파일에서 사이트를 클릭합니다.

  2. 빈 사이트를 선택하고 사이트 이름 상자에 "SmallBakery"를 입력한 다음 확인을 클릭합니다. 사이트가 만들어지고 WebMatrix에 표시됩니다.

  3. 왼쪽 창에서 데이터베이스 작업 영역을 클릭합니다.

  4. 리본에서 새 데이터베이스를 클릭합니다. 빈 데이터베이스는 사이트와 동일한 이름으로 만들어집니다.

  5. 왼쪽 창에서 SmallBakery.sdf 노드를 확장한 다음 테이블을 클릭합니다.

  6. 리본에서 새 테이블을 클릭합니다. WebMatrix는 테이블 디자이너를 엽니다.

    [스크린샷은 테이블 디자이너를 여는 웹 매트릭스를 보여줍니다.]

  7. 이름 열을 클릭하고 "Id"를 입력합니다.

  8. 데이터 형식 열에서 int를 선택합니다.

  9. 기본 키인가요?식별 여부 옵션을 예로 설정합니다.

    이름에서 알 수 있듯이 기본 키는 데이터베이스에 테이블의 기본 키가 될 것이라고 알려줍니다. ID는 모든 새 레코드에 대한 ID 번호를 자동으로 만들고 다음 순차 번호(1부터 시작)를 할당하도록 데이터베이스에 지시합니다.

  10. 다음 행을 클릭합니다. 편집기가 새 열 정의를 시작합니다.

  11. 이름 값에 "Name"을 입력합니다.

  12. 데이터 형식의 경우 "nvarchar"를 선택하고 길이를 50으로 설정합니다. 의 nvarcharvar 부분은 이 열의 데이터가 레코드마다 크기가 다를 수 있는 문자열이 되도록 데이터베이스에 지시합니다. ( n 접두사는 국가별 접두사로, 필드에 모든 알파벳 또는 쓰기 시스템을 나타내는 문자 데이터(즉, 필드에 유니코드 데이터가 포함됨)를 포함할 수 있음을 나타냅니다.

  13. Null 허용 옵션을 아니요로 설정합니다. 이렇게 하면 이름 열이 비워지지 않습니다.

  14. 이 동일한 프로세스를 사용하여 Description이라는 열을 만듭니다. 데이터 형식을 길이에 대해 "nvarchar"와 50으로 설정하고 Null 허용을 false로 설정합니다.

  15. Price라는 열을 만듭니다. 데이터 형식을 "money"로 설정하고 Null 허용을 false로 설정합니다.

  16. 맨 위에 있는 상자에서 테이블 이름을 "Product"로 지정합니다.

    완료되면 정의는 다음과 같이 표시됩니다.

    [스크린샷은 완료되면 정의가 어떻게 표시되는지 보여줍니다.]

  17. Ctrl+S를 눌러 테이블을 저장합니다.

데이터베이스에 데이터 추가

이제 문서의 뒷부분에서 사용할 몇 가지 샘플 데이터를 데이터베이스에 추가할 수 있습니다.

  1. 왼쪽 창에서 SmallBakery.sdf 노드를 확장한 다음 테이블을 클릭합니다.

  2. Product 테이블을 마우스 오른쪽 단추로 클릭한 다음 데이터를 클릭합니다.

  3. 편집 창에서 다음 레코드를 입력합니다.

    이름 설명 가격
    매일 신선한 구운. 2.99
    딸기 쇼트케이크 우리 정원에서 유기농 딸기로 만들었습니다. 9.99
    Apple Pie 둘째는 엄마의 파이에 불과합니다. 12.99
    피칸 파이 당신이 피칸을 좋아한다면, 이것은 당신을위한 것입니다. 10.99
    레몬 파이 세계 최고의 레몬으로 만든. 11.99
    컵케이크 당신의 아이들과 당신의 아이는이 사랑합니다. 7.99

    ID 열에 아무 것도 입력할 필요가 없습니다. ID 열을 만들 때 해당 Is Identity 속성을 true로 설정하면 자동으로 채워집니다.

    데이터 입력이 완료되면 테이블 디자이너는 다음과 같이 표시됩니다.

    [스크린샷은 데이터 입력이 완료되면 테이블 디자이너의 모양을 보여 줍니다.]

  4. 데이터베이스 데이터가 포함된 탭을 닫습니다.

데이터베이스의 데이터 표시

데이터가 포함된 데이터베이스가 있으면 ASP.NET 웹 페이지에 데이터를 표시할 수 있습니다. 표시할 테이블 행을 선택하려면 데이터베이스에 전달하는 명령인 SQL 문을 사용합니다.

  1. 왼쪽 창에서 파일 작업 영역을 클릭합니다.

  2. 웹 사이트의 루트에서 ListProducts.cshtml이라는 새 CSHTML 페이지를 만듭니다.

  3. 기존 태그를 다음으로 바꿉다.

    @{
        var db = Database.Open("SmallBakery");
        var selectQueryString = "SELECT * FROM Product ORDER BY Name";
     }
    <!DOCTYPE html>
    <html>
     <head>
       <title>Small Bakery Products</title>
       <style>
           table, th, td {
             border: solid 1px #bbbbbb;
             border-collapse: collapse;
             padding: 2px;
           }
        </style>
     </head>
     <body>
       <h1>Small Bakery Products</h1>
       <table>
           <thead>
               <tr>
                   <th>Id</th>
                   <th>Product</th>
                   <th>Description</th>
           <th>Price</th>
               </tr>
           </thead>
           <tbody>
               @foreach(var row in db.Query(selectQueryString)){
                <tr>
                   <td>@row.Id</td>
                       <td>@row.Name</td>
                       <td>@row.Description</td>
                       <td>@row.Price</td>
                </tr>
               }
           </tbody>
       </table>
     </body>
    </html>
    

    첫 번째 코드 블록에서 이전에 만든 SmallBakery.sdf 파일(데이터베이스)을 엽니다. 메서드는 Database.Open.sdf 파일이 웹 사이트의 App_Data 폴더에 있다고 가정합니다. ( .sdf 확장을 지정할 필요가 없습니다. 실제로 이렇게 하면 메서드가 Open 작동하지 않습니다.)

    참고

    App_Data 폴더는 데이터 파일을 저장하는 데 사용되는 ASP.NET 특수 폴더입니다. 자세한 내용은 이 문서의 뒷부 분에 있는 데이터베이스에 연결을 참조하세요.

    그런 다음, 다음 SQL Select 문을 사용하여 데이터베이스를 쿼리하도록 요청합니다.

    SELECT * FROM Product ORDER BY Name
    

    문에서 쿼리 Product 할 테이블을 식별합니다. 문자는 * 쿼리가 테이블의 모든 열을 반환해야 한다고 지정합니다. 일부 열만 표시하려면 열을 개별적으로 나열하고 쉼표로 구분할 수도 있습니다. 절은 Order By 데이터를 정렬하는 방법을 나타냅니다. 이 경우 Name 열을 기준으로 합니다. 즉, 데이터는 각 행의 Name 열 값에 따라 사전순으로 정렬됩니다.

    페이지 본문에서 태그는 데이터를 표시하는 데 사용할 HTML 테이블을 만듭니다. 요소 내에서 <tbody> 루프를 사용하여 쿼리에서 foreach 반환되는 각 데이터 행을 개별적으로 가져옵니다. 각 데이터 행에 대해 HTML 테이블 행(<tr> 요소)을 만듭니다. 그런 다음 각 열에 대한 HTML 테이블 셀(<td> 요소)을 만듭니다. 루프를 통과할 때마다 데이터베이스에서 사용할 수 있는 다음 행이 변수에 row 있습니다(문에서 foreach 설정). 행에서 개별 열을 얻으려면 또는 또는 row.Description 원하는 열의 이름을 사용할 row.Name 수 있습니다.

  4. 브라우저에서 페이지를 실행합니다. (실행하기 전에 파일 작업 영역에서 페이지가 선택되어 있는지 확인합니다.) 페이지에는 다음과 같은 목록이 표시됩니다.

    [스크린샷은 페이지가 브라우저에 표시할 목록을 보여줍니다.]

SQL(구조적 쿼리 언어)

SQL은 데이터베이스의 데이터를 관리하기 위해 대부분의 관계형 데이터베이스에서 사용되는 언어입니다. 여기에는 데이터를 검색하고 업데이트할 수 있고 데이터베이스 테이블을 만들고 수정하고 관리할 수 있는 명령이 포함되어 있습니다. SQL은 프로그래밍 언어(예: WebMatrix에서 사용 중인 언어)와 다릅니다. SQL에서는 데이터베이스에 원하는 내용을 알려주고 데이터를 가져오는 방법을 알아내거나 작업을 수행하는 것이 데이터베이스의 작업이라는 생각이 들기 때문입니다. 다음은 일부 SQL 명령의 예와 수행하는 작업입니다.

SELECT Id, Name, Price FROM Product WHERE Price > 10.00 ORDER BY Name

이렇게 하면 Price 값이 10보다 큰 경우 Product 테이블의 레코드에서 Id, NamePrice 열을 가져오고 Name 열의 값을 기준으로 결과를 사전순으로 반환합니다. 이 명령은 조건을 충족하는 레코드가 포함된 결과 집합을 반환하거나 일치하는 레코드가 없는 경우 빈 집합을 반환합니다.

INSERT INTO Product (Name, Description, Price) VALUES ("Croissant", "A flaky delight", 1.99)

이렇게 하면 Product 테이블에 새 레코드가 삽입되고 Name 열이 "Croissant"로 설정되고 설명 열이 "으스스한 기쁨"으로 설정되고 가격이 1.99로 설정됩니다.

DELETE FROM Product WHERE ExpirationDate < "01/01/2008"

이 명령은 만료 날짜 열이 2008년 1월 1일 이전인 Product 테이블의 레코드를 삭제합니다. 물론 Product 테이블에는 이러한 열이 있다고 가정합니다. 이 날짜는 MM/DD/YYYY 형식으로 입력되지만 로캘에 사용되는 형식으로 입력해야 합니다.

Insert IntoDelete 명령은 결과 집합을 반환하지 않습니다. 대신 명령의 영향을 받은 레코드 수를 알려주는 숫자를 반환합니다.

이러한 작업 중 일부(예: 레코드 삽입 및 삭제)의 경우 작업을 요청하는 프로세스에는 데이터베이스에 적절한 권한이 있어야 합니다. 따라서 프로덕션 데이터베이스의 경우 데이터베이스에 연결할 때 사용자 이름과 암호를 제공해야 하는 경우가 많습니다.

수십 개의 SQL 명령이 있지만 모두 다음과 같은 패턴을 따릅니다. SQL 명령을 사용하여 데이터베이스 테이블을 만들고, 테이블의 레코드 수를 계산하고, 가격을 계산하고, 더 많은 작업을 수행할 수 있습니다.

데이터베이스에 데이터 삽입

이 섹션에서는 사용자가 Product 데이터베이스 테이블에 새 제품을 추가할 수 있는 페이지를 만드는 방법을 보여 줍니다. 새 제품 레코드를 삽입한 후 페이지에는 이전 섹션에서 만든 ListProducts.cshtml 페이지를 사용하여 업데이트된 테이블이 표시됩니다.

페이지에는 사용자가 입력하는 데이터가 데이터베이스에 유효한지 확인하기 위한 유효성 검사가 포함되어 있습니다. 예를 들어 페이지의 코드는 모든 필수 열에 대해 값을 입력했는지 확인합니다.

  1. 웹 사이트에서 InsertProducts.cshtml이라는 새 CSHTML 파일을 만듭니다.

  2. 기존 태그를 다음으로 바꿉다.

    @{
        Validation.RequireField("Name", "Product name is required.");
        Validation.RequireField("Description", "Product description is required.");
        Validation.RequireField("Price", "Product price is required.");
    
        var db = Database.Open("SmallBakery");
        var Name = Request.Form["Name"];
        var Description = Request.Form["Description"];
        var Price = Request.Form["Price"];
    
        if (IsPost && Validation.IsValid()) {
            // Define the insert query. The values to assign to the
            // columns in the Product table are defined as parameters
            // with the VALUES keyword.
            if(ModelState.IsValid) {
                var insertQuery = "INSERT INTO Product (Name, Description, Price) " +
                    "VALUES (@0, @1, @2)";
                db.Execute(insertQuery, Name, Description, Price);
                // Display the page that lists products.
                Response.Redirect("~/ListProducts");
            }
        }
    }
    
    <!DOCTYPE html>
    <html>
    <head>
     <title>Add Products</title>
     <style type="text/css">
        label {float:left; width: 8em; text-align: right;
               margin-right: 0.5em;}
        fieldset {padding: 1em; border: 1px solid; width: 50em;}
        legend {padding: 2px 4px; border: 1px solid; font-weight:bold;}
        .validation-summary-errors {font-weight:bold; color:red;
               font-size: 11pt;}
     </style>
    </head>
    <body>
     <h1>Add New Product</h1>
    
     @Html.ValidationSummary("Errors with your submission:")
    
     <form method="post" action="">
       <fieldset>
         <legend>Add Product</legend>
         <div>
           <label>Name:</label>
           <input name="Name" type="text" size="50" value="@Name" />
         </div>
         <div>
           <label>Description:</label>
           <input name="Description" type="text" size="50"
               value="@Description" />
         </div>
         <div>
           <label>Price:</label>
           <input name="Price" type="text" size="50" value="@Price" />
         </div>
         <div>
           <label>&nbsp;</label>
           <input type="submit" value="Insert" class="submit" />
         </div>
       </fieldset>
     </form>
    </body>
    </html>
    

    페이지의 본문에는 사용자가 이름, 설명 및 가격을 입력할 수 있는 세 개의 텍스트 상자가 있는 HTML 양식이 포함되어 있습니다. 사용자가 삽입 단추를 클릭하면 페이지 맨 위에 있는 코드가 SmallBakery.sdf 데이터베이스에 대한 연결을 엽니다. 그런 다음, 개체를 사용하여 Request 사용자가 제출한 값을 가져와서 해당 값을 지역 변수에 할당합니다.

    사용자가 각 필수 열에 대한 값을 입력했는지 확인하려면 유효성을 검사할 각 <input> 요소를 등록합니다.

    Validation.RequireField("Name", "Product name is required.");
    Validation.RequireField("Description", "Product description is required.");
    Validation.RequireField("Price", "Product price is required.");
    

    도우미는 Validation 등록한 각 필드에 값이 있는지 확인합니다. 일반적으로 사용자로부터 받은 정보를 처리하기 전에 수행하는 를 확인하여 Validation.IsValid()모든 필드가 유효성 검사를 통과했는지 여부를 테스트할 수 있습니다.

    if (IsPost && Validation.IsValid()) {
        // Process information here
    }
    

    연산자는 && AND를 의미합니다. 이 테스트는 양식 제출이고 모든 필드가 유효성 검사를 통과한 경우입니다.

    모든 열의 유효성이 검사된 경우(비어 있지 않음) 계속 진행하여 SQL 문을 만들어 데이터를 삽입한 다음, 다음과 같이 실행합니다.

    var insertQuery =
        "INSERT INTO Product (Name, Description, Price) VALUES (@0, @1, @2)";
    

    삽입할 값의 경우 매개 변수 자리 표시자(@0, , @1@2)를 포함합니다.

    참고

    보안 예방 조치로, 앞의 예제와 같이 항상 매개 변수를 사용하여 SQL 문에 값을 전달합니다. 이렇게 하면 사용자의 데이터의 유효성을 검사할 수 있으며 데이터베이스에 악의적인 명령을 보내려는 시도(SQL 삽입 공격이라고도 함)로부터 보호할 수 있습니다.

    쿼리를 실행하려면 이 문을 사용하여 자리 표시자를 대체할 값이 포함된 변수를 전달합니다.

    db.Execute(insertQuery, Name, Description, Price);
    

    Insert Into 문이 실행된 후 다음 줄을 사용하여 제품을 나열하는 페이지로 사용자를 보냅니다.

    Response.Redirect("~/ListProducts");
    

    유효성 검사가 성공하지 못한 경우 삽입을 건너뜁니다. 대신 페이지에 누적된 오류 메시지(있는 경우)를 표시할 수 있는 도우미가 있습니다.

    @Html.ValidationSummary("Errors with your submission:")
    

    태그의 스타일 블록에는 라는 .validation-summary-errorsCSS 클래스 정의가 포함되어 있습니다. 유효성 검사 오류가 포함된 요소에 기본적으로 <div> 사용되는 CSS 클래스의 이름입니다. 이 경우 CSS 클래스는 유효성 검사 요약 오류가 빨간색과 굵게 표시되도록 지정하지만 원하는 서식을 표시하도록 클래스를 정의 .validation-summary-errors 할 수 있습니다.

삽입 페이지 테스트

  1. 브라우저에서 페이지를 봅니다. 페이지에는 다음 그림과 비슷한 양식이 표시됩니다.

    [스크린샷은 브라우저의 페이지에 표시되는 양식을 보여줍니다.]

  2. 모든 열에 대한 값을 입력하지만 가격 열을 비워 두어야 합니다.

  3. 삽입을 클릭합니다. 다음 그림과 같이 페이지에 오류 메시지가 표시됩니다. (새 레코드가 만들어지지 않습니다.)

    [스크린샷은 오류 메시지를 보여줍니다.]

  4. 양식을 완전히 채운 다음 삽입을 클릭합니다. 이번에는 ListProducts.cshtml 페이지가 표시되고 새 레코드가 표시됩니다.

데이터베이스에서 데이터 업데이트

테이블에 데이터를 입력한 후에는 데이터를 업데이트해야 할 수 있습니다. 이 절차에서는 이전에 데이터 삽입을 위해 만든 페이지와 유사한 두 페이지를 만드는 방법을 보여 줍니다. 첫 번째 페이지에는 제품이 표시되고 사용자가 변경할 제품을 선택할 수 있습니다. 두 번째 페이지에서는 사용자가 실제로 편집을 수행하고 저장할 수 있습니다.

참고

중요 프로덕션 웹 사이트에서는 일반적으로 데이터를 변경할 수 있는 사용자를 제한합니다. 멤버 자격을 설정하는 방법 및 사용자가 사이트에서 작업을 수행할 수 있도록 권한을 부여하는 방법에 대한 자세한 내용은 ASP.NET 웹 페이지 사이트에 보안 및 멤버 자격 추가를 참조하세요.

  1. 웹 사이트에서 EditProducts.cshtml이라는 새 CSHTML 파일을 만듭니다.

  2. 파일의 기존 태그를 다음으로 바꿉 있습니다.

    @{
        var db = Database.Open("SmallBakery");
        var selectQueryString = "SELECT * FROM Product ORDER BY Name";
    
    }
    <!DOCTYPE html>
    <html>
    <head>
        <title>Edit Products</title>
        <style type="text/css">
            table, th, td {
              border: solid 1px #bbbbbb;
              border-collapse: collapse;
              padding: 2px;
            }
        </style>
    </head>
    <body>
        <h1>Edit Small Bakery Products</h1>
        <table>
          <thead>
            <tr>
              <th>&nbsp;</th>
              <th>Name</th>
              <th>Description</th>
              <th>Price</th>
            </tr>
          </thead>
          <tbody>
            @foreach (var row in db.Query(selectQueryString)) {
              <tr>
                <td><a href="@Href("~/UpdateProducts", row.Id)">Edit</a></td>
                <td>@row.Name</td>
                <td>@row.Description</td>
                <td>@row.Price</td>
              </tr>
            }
          </tbody>
        </table>
    </body>
    </html>
    

    이 페이지와 이전의 ListProducts.cshtml 페이지 간의 유일한 차이점은 이 페이지의 HTML 테이블에 편집 링크를 표시하는 추가 열이 포함되어 있다는 것입니다. 이 링크를 클릭하면 선택한 레코드를 편집할 수 있는 UpdateProducts.cshtml 페이지(다음에 만들 예정)로 이동합니다.

    편집 링크를 만드는 코드를 확인합니다.

    <a href="@Href("~/UpdateProducts", row.Id)">Edit</a></td>
    

    이렇게 하면 특성이 href 동적으로 설정된 HTML <a> 요소가 만들어집니다. 특성은 href 사용자가 링크를 클릭할 때 표시할 페이지를 지정합니다. 또한 현재 행의 값을 링크에 전달합니다 Id . 페이지가 실행되면 페이지 원본에 다음과 같은 링크가 포함될 수 있습니다.

    <a href="UpdateProducts/1">Edit</a></td>
    <a href="UpdateProducts/2">Edit</a></td>
    <a href="UpdateProducts/3">Edit</a></td>
    

    특성이 href 로 설정되어 UpdateProducts/n있습니다. 여기서 n 은 제품 번호입니다. 사용자가 이러한 링크 중 하나를 클릭하면 결과 URL은 다음과 같이 표시됩니다.

    http://localhost:18816/UpdateProducts/6

    즉, 편집할 제품 번호가 URL에 전달됩니다.

  3. 브라우저에서 페이지를 봅니다. 페이지에는 다음과 같은 형식으로 데이터가 표시됩니다.

    [스크린샷은 브라우저의 페이지에 표시되는 데이터를 보여줍니다.]

    다음으로 사용자가 실제로 데이터를 업데이트할 수 있는 페이지를 만듭니다. 업데이트 페이지에는 사용자가 입력하는 데이터의 유효성을 검사하는 유효성 검사가 포함되어 있습니다. 예를 들어 페이지의 코드는 모든 필수 열에 대해 값이 입력되었는지 확인합니다.

  4. 웹 사이트에서 UpdateProducts.cshtml이라는 새 CSHTML 파일을 만듭니다.

  5. 파일의 기존 태그를 다음으로 바꿉다.

    @{
        Validation.RequireField("Name", "Product name is required.");
        Validation.RequireField("Description", "Product description is required.");
        Validation.RequireField("Price", "Product price is required.");
    
        var Name = "";
        var Description = "";
        var Price = Decimal.Zero;
    
        var ProductId  = UrlData[0];
        if (ProductId.IsEmpty()) {
             Response.Redirect("~/EditProducts");
        }
    
        var db = Database.Open("SmallBakery");
    
        if (IsPost && Validation.IsValid()) {
            var updateQueryString =
                "UPDATE Product SET Name=@0, Description=@1, Price=@2 WHERE Id=@3" ;
            Name = Request["Name"];
            Description = Request["Description"];
            Price = Request["Price"].AsDecimal();
            db.Execute(updateQueryString, Name, Description, Price, ProductId);
            Response.Redirect(@Href("~/EditProducts"));
        }
        else {
            var selectQueryString = "SELECT * FROM Product WHERE Id=@0";
    
            var row = db.QuerySingle(selectQueryString, ProductId);
            Name = row.Name;
            Description = row.Description;
            Price = row.Price;
        }
    
    }
    
    <!DOCTYPE html>
    <html>
    <head>
      <title>Add Products</title>
      <style type="text/css">
         label { float: left; width: 8em; text-align: right;
                 margin-right: 0.5em;}
         fieldset { padding: 1em; border: 1px solid; width: 35em;}
         legend { padding: 2px 4px;  border: 1px solid; font-weight: bold;}
         .validation-summary-errors {font-weight:bold; color:red; font-size:11pt;}
      </style>
    </head>
    <body>
      <h1>Update Product</h1>
       @Html.ValidationSummary("Errors with your submission:")
       <form method="post" action="">
         <fieldset>
           <legend>Update Product</legend>
           <div>
             <label>Name:</label>
             <input name="Name" type="text" size="50" value="@Name" />
           </div>
           <div>
             <label>Description:</label>
             <input name="Description" type="text" size="50"
                value="@Description" />
           </div>
           <div>
              <label>Price:</label>
              <input name="Price" type="text" size="50" value="@Price" />
           </div>
           <div>
              <label>&nbsp;</label>
              <input type="submit" value="Update" class="submit" />
           </div>
        </fieldset>
      </form>
    </body>
    </html>
    

    페이지의 본문에는 제품이 표시되고 사용자가 편집할 수 있는 HTML 양식이 포함되어 있습니다. 제품을 표시하려면 다음 SQL 문을 사용합니다.

    SELECT * FROM Product WHERE Id=@0
    

    그러면 ID가 매개 변수에 전달된 값과 일치하는 제품이 선택됩니다 @0 . ID는 기본 키이므로 고유해야 하므로 이러한 방식으로 하나의 제품 레코드만 선택할 수 있습니다. 이 Select 문에 전달할 ID 값을 가져오려면 다음 구문을 사용하여 URL의 일부로 페이지에 전달된 값을 읽을 수 있습니다.

    var ProductId  = UrlData[0];
    

    실제로 제품 레코드를 가져오려면 메서드를 QuerySingle 사용하여 하나의 레코드만 반환합니다.

    var row = db.QuerySingle(selectQueryString, ProductId);
    

    단일 행이 변수에 row 반환됩니다. 각 열에서 데이터를 가져와 다음과 같이 지역 변수에 할당할 수 있습니다.

    var Name = row.Name;
    var Description = row.Description;
    var Price = row.Price;
    

    양식의 태그에서 이러한 값은 다음과 같은 포함된 코드를 사용하여 개별 텍스트 상자에 자동으로 표시됩니다.

    <input name="Name" type="text" size="50" value="@Name" />
    

    코드의 해당 부분에 업데이트할 제품 레코드가 표시됩니다. 레코드가 표시되면 사용자는 개별 열을 편집할 수 있습니다.

    사용자가 업데이트 단추를 클릭하여 양식을 제출하면 블록의 코드가 if(IsPost) 실행됩니다. 이렇게 하면 개체에서 Request 사용자의 값을 가져오고, 값을 변수에 저장하고, 각 열이 채워졌는지 확인합니다. 유효성 검사를 통과하면 코드는 다음 SQL Update 문을 만듭니다.

    UPDATE Product SET Name=@0, Description=@1, Price=@2, WHERE ID=@3
    

    SQL Update 문에서 업데이트할 각 열과 설정할 값을 지정합니다. 이 코드에서 값은 매개 변수 자리 표시자 @0, , @1@2등을 사용하여 지정됩니다. 앞에서 설명한 대로 보안을 위해 항상 매개 변수를 사용하여 SQL 문에 값을 전달해야 합니다.

    메서드를 db.Execute 호출할 때 SQL 문의 매개 변수에 해당하는 순서대로 값을 포함하는 변수를 전달합니다.

    db.Execute(updateQueryString, Name, Description, Price, ProductId);
    

    Update 문이 실행된 후 다음 메서드를 호출하여 사용자를 편집 페이지로 다시 리디렉션합니다.

    Response.Redirect(@Href("~/EditProducts"));
    

    그 효과는 사용자가 데이터베이스의 업데이트된 데이터 목록을 보고 다른 제품을 편집할 수 있다는 것입니다.

  6. 페이지를 저장합니다.

  7. EditProducts.cshtml 페이지(업데이트 페이지 아님)를 실행한 다음 편집을 클릭하여 편집할 제품을 선택합니다. UpdateProducts.cshtml 페이지가 표시되어 선택한 레코드가 표시됩니다.

    [스크린샷은 선택한 레코드와 함께 제품 업데이트 페이지를 보여줍니다.]

  8. 변경하고 업데이트를 클릭합니다. 제품 목록이 업데이트된 데이터와 함께 다시 표시됩니다.

데이터베이스에서 데이터 삭제

이 섹션에서는 사용자가 Product 데이터베이스 테이블에서 제품을 삭제하도록 하는 방법을 보여줍니다. 이 예제는 두 페이지로 구성됩니다. 첫 번째 페이지에서 사용자는 삭제할 레코드를 선택합니다. 삭제할 레코드는 레코드를 삭제할 것인지 확인할 수 있는 두 번째 페이지에 표시됩니다.

참고

중요 프로덕션 웹 사이트에서는 일반적으로 데이터를 변경할 수 있는 사용자를 제한합니다. 멤버 자격을 설정하는 방법 및 사이트에서 작업을 수행할 수 있도록 사용자에게 권한을 부여하는 방법에 대한 자세한 내용은 ASP.NET 웹 페이지 사이트에 보안 및 멤버 자격 추가를 참조하세요.

  1. 웹 사이트에서 ListProductsForDelete.cshtml이라는 새 CSHTML 파일을 만듭니다.

  2. 기존 태그를 다음으로 바꿉다.

    @{
      var db = Database.Open("SmallBakery");
      var selectQueryString = "SELECT * FROM Product ORDER BY Name";
    }
    <!DOCTYPE html>
    <html>
    <head>
        <title>Delete a Product</title>
        <style>
            table, th, td {
              border: solid 1px #bbbbbb;
              border-collapse: collapse;
              padding: 2px;
            }
         </style>
    </head>
    <body>
      <h1>Delete a Product</h1>
      <form method="post" action="" name="form">
        <table border="1">
          <thead>
            <tr>
              <th>&nbsp;</th>
              <th>Name</th>
              <th>Description</th>
              <th>Price</th>
            </tr>
          </thead>
          <tbody>
            @foreach (var row in db.Query(selectQueryString)) {
              <tr>
                <td><a href="@Href("~/DeleteProduct", row.Id)">Delete</a></td>
                <td>@row.Name</td>
                <td>@row.Description</td>
                <td>@row.Price</td>
              </tr>
            }
          </tbody>
        </table>
      </form>
    </body>
    </html>
    

    이 페이지는 이전의 EditProducts.cshtml 페이지와 비슷합니다. 그러나 각 제품에 대한 편집 링크를 표시하는 대신 삭제 링크가 표시됩니다. 삭제 링크는 태그에 포함된 다음 코드를 사용하여 만들어집니다.

    <a href="@Href("~/DeleteProduct", row.Id)">Delete</a>
    

    그러면 사용자가 링크를 클릭할 때 다음과 같은 URL이 만들어집니다.

    http://<server>/DeleteProduct/4

    URL은 DeleteProduct.cshtml (다음에 만들 예정)이라는 페이지를 호출하고 삭제할 제품의 ID를 전달합니다(여기, 4).

  3. 파일을 저장하지만 열어 둡니다.

  4. DeleteProduct.cshtml이라는 다른 CHTML 파일을 만듭니다. 기존 콘텐츠를 다음으로 바꿉다.

    @{
      var db = Database.Open("SmallBakery");
      var ProductId = UrlData[0];
      if (ProductId.IsEmpty()) {
        Response.Redirect("~/ListProductsForDelete");
      }
      var prod = db.QuerySingle("SELECT * FROM PRODUCT WHERE ID = @0", ProductId);
      if( IsPost && !ProductId.IsEmpty()) {
        var deleteQueryString = "DELETE FROM Product WHERE Id=@0";
        db.Execute(deleteQueryString, ProductId);
        Response.Redirect("~/ListProductsForDelete");
      }
    }
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>Delete Product</title>
    </head>
    <body>
      <h1>Delete Product - Confirmation</h1>
      <form method="post" action="" name="form">
        <p>Are you sure you want to delete the following product?</p>
    
        <p>Name: @prod.Name <br />
           Description: @prod.Description <br />
           Price: @prod.Price</p>
        <p><input type="submit" value="Delete" /></p>
      </form>
    </body>
    </html>
    

    이 페이지는 ListProductsForDelete.cshtml 에서 호출되며 사용자가 제품을 삭제할 것인지 확인할 수 있습니다. 삭제할 제품을 나열하려면 다음 코드를 사용하여 URL에서 삭제할 제품의 ID를 가져옵니다.

    var ProductId = UrlData[0];
    

    그러면 페이지에서 사용자에게 실제로 레코드를 삭제하는 단추를 클릭하도록 요청합니다. 이는 중요한 보안 조치입니다. 웹 사이트에서 데이터 업데이트 또는 삭제와 같은 중요한 작업을 수행하는 경우 이러한 작업은 GET 작업이 아닌 POST 작업을 사용하여 항상 수행해야 합니다. GET 작업을 사용하여 삭제 작업을 수행할 수 있도록 사이트를 설정한 경우 누구나 같은 http://<server>/DeleteProduct/4 URL을 전달하고 데이터베이스에서 원하는 모든 항목을 삭제할 수 있습니다. POST를 통해서만 삭제를 수행할 수 있도록 확인을 추가하고 페이지를 코딩하면 사이트에 보안 측정값을 추가합니다.

    실제 삭제 작업은 다음 코드를 사용하여 수행됩니다. 이 코드는 먼저 이 작업이 사후 작업이며 ID가 비어 있지 않음을 확인합니다.

    if( IsPost && !ProductId.IsEmpty()) {
        var deleteQueryString = "DELETE FROM Product WHERE Id=@0";
        db.Execute(deleteQueryString, ProductId);
        Response.Redirect("~/ListProductsForDelete");
    }
    

    이 코드는 지정된 레코드를 삭제한 다음 사용자를 목록 페이지로 다시 리디렉션하는 SQL 문을 실행합니다.

  5. 브라우저에서 ListProductsForDelete.cshtml 을 실행합니다.

    [스크린샷은 브라우저에서 점 CSHTML을 삭제하기 위한 실행 중인 목록 제품을 보여줍니다.]

  6. 제품 중 하나에 대한 삭제 링크를 클릭합니다. DeleteProduct.cshtml 페이지가 표시되어 해당 레코드를 삭제할 것인지 확인합니다.

  7. 삭제 단추를 클릭합니다. 제품 레코드가 삭제되고 업데이트된 제품 목록으로 페이지가 새로 고쳐집니다.

데이터베이스에 연결

두 가지 방법으로 데이터베이스에 연결할 수 있습니다. 첫 번째는 메서드를 Database.Open 사용하고 데이터베이스 파일의 이름( .sdf 확장명보다 작음)을 지정하는 것입니다.

var db = Database.Open("SmallBakery");

메서드는 Open 를 가정합니다.sdf 파일은 웹 사이트의 App_Data 폴더에 있습니다. 이 폴더는 데이터를 보관하기 위해 특별히 설계되었습니다. 예를 들어 웹 사이트에서 데이터를 읽고 쓸 수 있는 적절한 권한이 있으며, 보안 조치로 WebMatrix는 이 폴더의 파일에 대한 액세스를 허용하지 않습니다.

두 번째 방법은 연결 문자열을 사용하는 것입니다. 데이터베이스에 연결하는 방법에 대한 정보를 포함하는 연결 문자열입니다. 여기에는 파일 경로가 포함되거나 로컬 또는 원격 서버의 SQL Server 데이터베이스 이름과 해당 서버에 연결할 사용자 이름 및 암호가 포함될 수 있습니다. (호스팅 공급자의 사이트와 같이 중앙에서 관리되는 버전의 SQL Server 데이터를 유지하는 경우 항상 연결 문자열을 사용하여 데이터베이스 연결 정보를 지정합니다.)

WebMatrix에서 연결 문자열은 일반적으로 Web.config라는 XML 파일에 저장됩니다. 이름에서 알 수 있듯이 웹 사이트의 루트에 Web.config 파일을 사용하여 사이트에 필요할 수 있는 연결 문자열을 포함하여 사이트의 구성 정보를 저장할 수 있습니다. Web.config 파일의 연결 문자열 예제는 다음과 같습니다. 참고 $CREDENTIAL_PLACEHOLDER$ 는 암호 키/값 쌍의 자리 표시자입니다.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
   <add
     name="SQLServerConnectionString"
     connectionString= "server=myServer;database=myDatabase;uid=username;$CREDENTIAL_PLACEHOLDER$"
     providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>

이 예제에서 연결 문자열은 로컬 .sdf 파일이 아닌 어딘가에 있는 서버에서 실행되는 SQL Server instance 있는 데이터베이스를 가리킵니다. 및 에 적절한 이름을 대체하고 및 에 SQL Server 로그인 값을 지정해야 합니다passwordusername.myServermyDatabase (사용자 이름 및 암호 값이 반드시 Windows 자격 증명과 동일하거나 호스팅 공급자가 서버에 로그인하기 위해 제공한 값과 동일하지는 않습니다. 필요한 정확한 값은 관리자에게 문의하세요.)

메서드는 Database.Open 데이터베이스 .sdf 파일의 이름 또는Web.config파일에 저장된 연결 문자열의 이름을 전달할 수 있으므로 유연합니다. 다음 예제에서는 이전 예제에 설명된 연결 문자열을 사용하여 데이터베이스에 연결하는 방법을 보여줍니다.

@{
    var db = Database.Open("SQLServerConnectionString");
}

앞에서 설명한 대로 메서드를 Database.Open 사용하면 데이터베이스 이름 또는 연결 문자열을 전달할 수 있으며 사용할 항목을 파악할 수 있습니다. 이는 웹 사이트를 배포(게시)할 때 매우 유용합니다. 사이트를 개발하고 테스트할 때 App_Data 폴더에서 .sdf 파일을 사용할 수 있습니다. 그런 다음 사이트를 프로덕션 서버로 이동할 때 코드를 변경하지 않고도 .sdf 파일과 이름이 같지만 호스팅 공급자의 데이터베이스를 가리키는 연결 문자열을 Web.config 파일에서 사용할 수 있습니다.

마지막으로 연결 문자열을 직접 사용하려는 경우 메서드를 호출 Database.OpenConnectionString 하고 Web.config 파일에 있는 이름 대신 실제 연결 문자열을 전달할 수 있습니다. 이는 어떤 이유로든 페이지가 실행될 때까지 연결 문자열(또는 .sdf 파일 이름과 같은 값)에 액세스할 수 없는 경우에 유용할 수 있습니다. 그러나 대부분의 시나리오에서는 이 문서에 설명된 대로 를 사용할 Database.Open 수 있습니다.

추가 리소스