ObjectDataSource 컨트롤에 매개 변수 사용

Visual Studio 2010

업데이트: 2007년 11월

ObjectDataSource 컨트롤은 SelectMethod, InsertMethod, UpdateMethod 또는 DeleteMethod 속성으로 식별되는 메서드의 이름뿐만 아니라 비즈니스 개체 메서드의 시그니처를 구성하는 매개 변수 이름을 기반으로 비즈니스 개체 메서드를 호출합니다. 비즈니스 개체에서 메서드를 만들 경우에는 비즈니스 개체 메서드에서 허용하는 매개 변수 이름 및 형식이 ObjectDataSource 컨트롤에서 전달하는 매개 변수 이름 및 형식과 일치해야 합니다. 매개 변수의 순서는 중요하지 않습니다.

모든 데이터 소스 컨트롤과 마찬가지로 ObjectDataSource 컨트롤은 런타임에 입력 매개 변수를 받고 매개 변수 컬렉션에서 이러한 매개 변수를 관리합니다. 각 데이터 작업에는 관련된 매개 변수 컬렉션이 있습니다. 예를 들어 선택 작업을 수행하는 경우 SelectParameters 컬렉션을 사용할 수 있으며 업데이트 작업을 수행할 경우에는 UpdateParameters 컬렉션을 사용할 수 있습니다.

각 매개 변수에 대해 이름, 형식, 방향 및 기본값을 지정할 수 있습니다. 컨트롤, 세션 변수 또는 사용자 프로필과 같은 특정 개체로부터 값을 가져오는 매개 변수를 사용하려면 추가 속성을 설정해야 합니다. 예를 들어 ControlParameter 개체를 사용하려면 ControlID 속성을 설정하여 매개 변수 값을 가져오는 컨트롤을 식별하고, PropertyName 속성을 설정하여 매개 변수 값이 포함된 속성을 식별해야 합니다. 자세한 내용은 데이터 소스 컨트롤에 매개 변수 사용을 참조하십시오.

다음 코드 예제에서는 ObjectDataSource 컨트롤에서 호출할 수 있는 select 메서드를 보여 줍니다. 이 메서드는 매개 변수를 사용하고 데이터 소스에서 단일 레코드를 선택합니다.

[DataObjectMethod(DataObjectMethodType.Select)]
public static DataTable GetEmployee(int EmployeeID)
{
  if (!_initialized) { Initialize(); }

  SqlConnection conn = new SqlConnection(_connectionString);
  SqlDataAdapter da  = 
    new SqlDataAdapter("SELECT EmployeeID, LastName, FirstName, Address, City, Region, PostalCode FROM Employees WHERE EmployeeID = @EmployeeID", conn); 
  da.SelectCommand.Parameters.Add("@EmployeeID", SqlDbType.Int).Value = EmployeeID;

  DataSet ds =  new DataSet(); 

  try
  {
    conn.Open();
    da.Fill(ds, "Employees");
  }
  catch (SqlException e)
  {
    // Handle exception.
  }
  finally
  {
    conn.Close();
  }

  if (ds.Tables["Employees"] != null)
    return ds.Tables["Employees"];

  return null;
}


ObjectDataSource 컨트롤에서는 각각 InsertParameters, UpdateParametersDeleteParameters 컬렉션을 기반으로 삽입, 업데이트 또는 삭제 작업에 호출할 메서드를 결정합니다. 또한 ObjectDataSource 컨트롤은 자동 업데이트, 삽입 및 삭제 작업을 지원하는 데이터 바인딩 컨트롤(예: GridView 또는 FormView 컨트롤)에 의해 전달된 값에 따라 자동으로 매개 변수를 만듭니다. 자세한 내용은 데이터 소스 컨트롤에서 데이터 바인딩된 필드에 대해 매개 변수가 생성되는 방식을 참조하십시오.

다음 코드 예제에서는 ObjectDataSource 컨트롤에서 호출할 수 있는 메서드를 보여 줍니다. 이 메서드는 Northwind 샘플 데이터베이스의 직원 정보를 업데이트합니다.

[DataObjectMethod(DataObjectMethodType.Update)]
public static bool UpdateEmployee(int EmployeeID, string FirstName, string LastName, 
                                  string Address, string City, string Region, string PostalCode)
{
  if (String.IsNullOrEmpty(FirstName))
    throw new ArgumentException("FirstName cannot be null or an empty string.");
  if (String.IsNullOrEmpty(LastName))
    throw new ArgumentException("LastName cannot be null or an empty string.");

  if (Address    == null) { Address    = String.Empty; }
  if (City       == null) { City       = String.Empty; }
  if (Region     == null) { Region     = String.Empty; }
  if (PostalCode == null) { PostalCode = String.Empty; }

  if (!_initialized) { Initialize(); }

  SqlConnection conn = new SqlConnection(_connectionString);
  SqlCommand    cmd  = new SqlCommand("UPDATE Employees " + 
                                      "  SET FirstName=@FirstName, LastName=@LastName, " + 
                                      "  Address=@Address, City=@City, Region=@Region, " +
                                      "  PostalCode=@PostalCode " +
                                      "  WHERE EmployeeID=@EmployeeID", conn);  

  cmd.Parameters.Add("@FirstName",  SqlDbType.VarChar, 10).Value = FirstName;
  cmd.Parameters.Add("@LastName",   SqlDbType.VarChar, 20).Value = LastName;
  cmd.Parameters.Add("@Address",    SqlDbType.VarChar, 60).Value = Address;
  cmd.Parameters.Add("@City",       SqlDbType.VarChar, 15).Value = City;
  cmd.Parameters.Add("@Region",     SqlDbType.VarChar, 15).Value = Region;
  cmd.Parameters.Add("@PostalCode", SqlDbType.VarChar, 10).Value = PostalCode;
  cmd.Parameters.Add("@EmployeeID", SqlDbType.Int).Value = EmployeeID;

  try
  {
    conn.Open();

    if (cmd.ExecuteNonQuery() == 0)
      return false;
  }
  catch (SqlException e)
  {
    // Handle exception.
  }
  finally
  {
    conn.Close();
  }

  return true;
}


이 코드 예제에서는 ObjectDataSource 컨트롤의 ConflictDetection 속성이 OverwriteChanges로 설정되어 있다고 가정합니다. ConflictDetection 속성이 CompareAllValues로 설정되면 비즈니스 개체 메서드에서 데이터 필드의 원래 값에 대한 매개 변수를 사용해야 합니다. OldValuesParameterFormatString 속성을 사용하여 현재 값 매개 변수와 원래 값 매개 변수를 구별할 수 있습니다. 원래 값 매개 변수에 대한 이름 형식을 지정하는 데 사용되는 문자열 식을 OldValuesParameterFormatString 속성에 설정합니다. 이때 {0} 문자는 필드 이름을 나타냅니다. 예를 들어 OldValuesParameterFormatString 속성을 original_{0}(으)로 설정하면 FirstName 필드의 현재 값이 FirstName 매개 변수에 전달되고 필드의 원래 값이 original_FirstName 매개 변수에 전달됩니다.

Select 비즈니스 개체 메서드에 대한 SelectParameters 개체를 지정할 수 있을 뿐만 아니라 정렬 및 페이징에 사용할 매개 변수를 포함할 수도 있습니다. 이렇게 하면 데이터 소스 개체의 데이터를 정렬할 수 있으며 요청한 데이터 페이지만 데이터 소스 개체에서 반환되도록 결과를 제한할 수 있습니다.

정렬 매개 변수 식별

ObjectDataSource 컨트롤의 SortParameterName 속성을 사용하여 Select 비즈니스 개체 메서드에 대한 정렬 매개 변수를 지정할 수 있습니다. SortParameterName 속성은 정렬 열 이름을 비즈니스 개체 메서드에 전달하는 데 사용되는 매개 변수의 이름을 식별합니다. 이 매개 변수는 문자열 형식입니다.

GridView와 같은 특정 데이터 바인딩 컨트롤에서는 정렬 매개 변수를 ObjectDataSource 컨트롤에 자동으로 전달할 수 있습니다. 정렬을 지원하는 데이터 바인딩 컨트롤이 ObjectDataSource 컨트롤에 바인딩되면 이 데이터 바인딩 컨트롤에서는 결과를 정렬하는 데 사용할 데이터 열을 식별하는 정렬 식을 전달합니다. 예를 들어 GridView 컨트롤은 SortExpression 속성에 정렬 값을 전달합니다. ObjectDataSource 컨트롤은 전달된 정렬 식을 기반으로 SortParameterName 속성에 의해 식별된 매개 변수의 값을 설정합니다. 정렬 식에는 열을 두 개 이상 지정할 수 있으며 이런 경우 열 이름이 쉼표로 구분됩니다. 내림차순 정렬을 지정하려면 정렬 식에 정렬 열 이름과 DESC 한정자를 차례로 포함할 수 있습니다. 예를 들어 LastName과 FirstName 열을 정렬 열로 식별하는 정렬 식은 오름차순 정렬일 경우 "LastName, FirstName"이 되고 내림차순 정렬일 경우에는 "LastName, FirstName DESC"가 됩니다.

페이징 매개 변수 식별

반환할 데이터 페이지를 식별하는 추가 매개 변수를 Select 메서드에 지정할 수 있습니다. ObjectDataSource 컨트롤에서는 다음과 같이 페이징 매개 변수를 식별하는 두 가지 속성을 지원합니다.

  • StartRowIndexParameterName 속성은 비즈니스 개체의 select 메서드에서 데이터 페이지의 시작 행을 지정하는 데 사용되는 매개 변수 이름을 식별합니다.

  • MaximumRowsParameterName 속성은 비즈니스 개체의 select 메서드에서 데이터 페이지의 행 수를 지정하는 데 사용되는 매개 변수 이름을 식별합니다.

StartRowIndexParameterNameMaximumRowsParameterName 속성에 의해 식별된 두 매개 변수의 형식은 모두 Int32입니다.

다음 코드 예제에서는 지정된 비즈니스 개체의 Select 메서드에 정렬 및 페이지 매개 변수를 전달하도록 구성된 ObjectDataSource 컨트롤을 보여 줍니다.

<asp:ObjectDataSource 
  ID="EmployeesObjectDataSource" 
  runat="server" 
  TypeName="Samples.AspNet.Controls.NorthwindEmployee" 
  SortParameterName="SortColumns"
  EnablePaging="true"
  StartRowIndexParameterName="StartRecord"
  MaximumRowsParameterName="MaxRecords" 
  SelectMethod="GetAllEmployees" >
</asp:ObjectDataSource>


다음 코드 예제에서는 위의 예제에서 호출된 Select 비즈니스 개체 메서드를 보여 줍니다. 이 비즈니스 개체 메서드는 Northwind 샘플 데이터베이스에서 지정된 순서로 정렬된 데이터 페이지를 반환합니다.

public static void Initialize()
{
  // Initialize data source. Use "Northwind" connection string from configuration.

  if (ConfigurationManager.ConnectionStrings["Northwind"] == null ||
      ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString.Trim() == "")
  {
    throw new Exception("A connection string named 'Northwind' with a valid connection string " + 
                        "must exist in the <connectionStrings> configuration section for the application.");
  }

  _connectionString = 
    ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;

  _initialized = true;
}


// Select all employees.

[DataObjectMethod(DataObjectMethodType.Select, true)]
public static DataTable GetAllEmployees(string sortColumns, int startRecord, int maxRecords)
{
  VerifySortColumns(sortColumns);

  if (!_initialized) { Initialize(); }

  string sqlCommand = "SELECT EmployeeID, LastName, FirstName, Address, City, Region, PostalCode FROM Employees ";

  if (sortColumns.Trim() == "")
    sqlCommand += "ORDER BY EmployeeID";
  else
    sqlCommand += "ORDER BY " + sortColumns;

  SqlConnection conn = new SqlConnection(_connectionString);
  SqlDataAdapter da  = new SqlDataAdapter(sqlCommand, conn); 

  DataSet ds =  new DataSet(); 

  try
  {
    conn.Open();
    da.Fill(ds, startRecord, maxRecords, "Employees");
  }
  catch (SqlException e)
  {
    // Handle exception.
  }
  finally
  {
    conn.Close();
  }

  if (ds.Tables["Employees"] != null)
    return ds.Tables["Employees"];

  return null;
}


//////////
// Verify that only valid columns are specified in the sort expression to avoid a SQL Injection attack.

private static void VerifySortColumns(string sortColumns)
{
  if (sortColumns.ToLowerInvariant().EndsWith(" desc"))
    sortColumns = sortColumns.Substring(0, sortColumns.Length - 5);

  string[] columnNames = sortColumns.Split(',');

  foreach (string columnName in columnNames)
  {
    switch (columnName.Trim().ToLowerInvariant())
    {
      case "employeeid":
        break;
      case "lastname":
        break;
      case "firstname":
        break;
      case "":
        break;
      default:
        throw new ArgumentException("SortColumns contains an invalid column name.");
        break;
    }
  }
}


기본적으로 비즈니스 개체 메서드의 모든 매개 변수는 입력 매개 변수입니다. ObjectDataSource 컨트롤에 값을 반환하는 out 매개 변수가 비즈니스 개체 메서드에 포함된 경우에는 데이터 소스 컨트롤에 매개 변수 사용 단원에서 설명하는 대로 매개 변수 방향을 사용하여 매개 변수를 명시적으로 지정해야 합니다.

다음 코드 예제에서는 Int32 형식의 출력 매개 변수를 받도록 구성된 ObjectDataSource 컨트롤을 보여 줍니다. out 매개 변수는 InsertMethod 속성에서 지정한 메서드에서 자동으로 생성한 기본 키 값을 반환합니다.

<asp:ObjectDataSource 
  ID="EmployeeDetailsObjectDataSource" 
  runat="server" 
  TypeName="Samples.AspNet.Controls.NorthwindEmployee" 
  SelectMethod="GetEmployee" 
  UpdateMethod="UpdateEmployee"
  DeleteMethod="DeleteEmployee"
  InsertMethod="InsertEmployee" 
  OnInserted="EmployeeDetailsObjectDataSource_OnInserted" >
  <SelectParameters>
    <asp:Parameter Name="EmployeeID" />  
  </SelectParameters>
  <InsertParameters>
    <asp:Parameter Name="NewEmployeeID" Direction="Output" 
                   Type="Int32" DefaultValue="0" />
  </InsertParameters>
</asp:ObjectDataSource>


다음 코드 예제에서는 기본 키 값을 out 매개 변수로 반환하는 Insert 비즈니스 개체 메서드를 보여 줍니다.

[DataObjectMethod(DataObjectMethodType.Insert)]
public static bool InsertEmployee(out int NewEmployeeID, string FirstName, string LastName, 
                                  string Address, string City, string Region, string PostalCode)
{
  if (String.IsNullOrEmpty(FirstName))
    throw new ArgumentException("FirstName cannot be null or an empty string.");
  if (String.IsNullOrEmpty(LastName))
    throw new ArgumentException("LastName cannot be null or an empty string.");

  if (Address    == null) { Address    = String.Empty; }
  if (City       == null) { City       = String.Empty; }
  if (Region     == null) { Region     = String.Empty; }
  if (PostalCode == null) { PostalCode = String.Empty; }

  if (!_initialized) { Initialize(); }

  NewEmployeeID = -1;

  SqlConnection conn = new SqlConnection(_connectionString);
  SqlCommand    cmd  = new SqlCommand("INSERT INTO Employees " + 
                                      "  (FirstName, LastName, Address, City, Region, PostalCode) " +
                                      "  Values(@FirstName, @LastName, @Address, @City, @Region, @PostalCode); " +
                                      "SELECT @EmployeeID = SCOPE_IDENTITY()", conn);  

  cmd.Parameters.Add("@FirstName",  SqlDbType.VarChar, 10).Value = FirstName;
  cmd.Parameters.Add("@LastName",   SqlDbType.VarChar, 20).Value = LastName;
  cmd.Parameters.Add("@Address",    SqlDbType.VarChar, 60).Value = Address;
  cmd.Parameters.Add("@City",       SqlDbType.VarChar, 15).Value = City;
  cmd.Parameters.Add("@Region",     SqlDbType.VarChar, 15).Value = Region;
  cmd.Parameters.Add("@PostalCode", SqlDbType.VarChar, 10).Value = PostalCode;
  SqlParameter p = cmd.Parameters.Add("@EmployeeID", SqlDbType.Int);
  p.Direction = ParameterDirection.Output;

  try
  {
    conn.Open();

    cmd.ExecuteNonQuery();

    NewEmployeeID = (int)p.Value;
  }
  catch (SqlException e)
  {
    // Handle exception.
  }
  finally
  {
    conn.Close();
  }

  return true;
}


기본적으로 비즈니스 개체 메서드의 모든 매개 변수는 Object로 형식화됩니다. 비즈니스 개체 메서드에 다른 형식의 매개 변수가 포함될 경우에는 강력한 형식의 매개 변수를 명시적으로 지정해야 합니다. 자세한 내용은 데이터 소스 컨트롤에 매개 변수 사용을 참조하십시오.

대부분의 비즈니스 개체 메서드 시그니처에는 StringInt32 형식의 매개 변수가 사용됩니다. 그러나 복합 형식 또는 사용자 정의 형식으로 형식화된 매개 변수를 하나 이상 사용하는 비즈니스 개체 메서드로 작업할 경우도 있습니다. 복합 형식 또는 사용자 정의 매개 변수 형식으로 작업하려면 ObjectDataSource 컨트롤의 DataObjectTypeName 속성을 사용하면 됩니다.

비즈니스 개체에서 컨트롤 값을 일대일로 데이터 저장소 값에 매핑하는 긴 매개 변수 목록을 사용하여 메서드를 만들면 쉽게 재사용할 수 없는 코드가 생성될 수 있습니다. 데이터를 사용자 지정 클래스에 캡슐화한 다음 클래스 인스턴스를 매개 변수로 전달하는 방법을 사용하는 것이 좋습니다. 그러면 클래스 인스턴스를 구성하는 데이터(예: 직원 레코드)를 변경할 때 데이터 소스 개체에 의해 노출된 공용 인터페이스를 변경할 필요가 없습니다. 다음 코드 예제에서는 직원 데이터를 정의하고 비즈니스 개체에 매개 변수로 전달될 수 있는 NorthwindExployee 클래스를 보여 줍니다.

public class NorthwindEmployee {
    public NorthwindEmployee() { }
    private int _empId;
    private string _firstName;
    public int EmpId {
      get { return _empId; }
      set { _empId = value; }
    }
    public string FirstName {
      get { return _firstName; }
      set { _firstName = value; }
    }
    // Additional code for the class.
}

위에 나온 클래스의 인스턴스를 매개 변수로 사용하기 위해 다음 시그니처를 사용하여 비즈니스 개체의 UpdateEmployeeInfo 메서드를 정의할 수 있습니다.

public void UpdateEmployeeInfo(NorthwindEmployee emp) {
}

매개 변수의 Type을 사용자 지정 클래스의 이름으로 설정할 수 없지만 ObjectDataSource 컨트롤의 DataObjectTypeName 속성을 사용자 정의 형식의 이름(예: NorthwindEmployee 클래스)으로 설정한 다음 이 형식의 인스턴스를 비즈니스 개체 데이터 메서드에 전달할 수 있습니다. 사용자 정의 개체를 데이터 소스 개체에 전달하려면 다음 조건이 충족되어야 합니다.

  • 사용자 정의 형식에 기본 생성자, 즉 매개 변수를 사용하지 않는 생성자가 있어야 합니다.

  • GridViewDetailsView와 같은 데이터 바인딩 컨트롤에서 데이터 소스 컨트롤에 전달한 사전 항목과 이름이 일치하는 공용 속성을 사용자 정의 형식에 정의해야 합니다. 이러한 사전에 대한 자세한 내용은 데이터 소스 컨트롤에 매개 변수 사용을 참조하십시오.

  • 데이터 소스 개체의 공용 속성에서는 get 접근자와 set 접근자를 모두 노출해야 합니다.

다음 예제에서는 EmployeeLogic이라는 비즈니스 개체의 UpdateEmployeeInfo 메서드를 호출하여 업데이트 작업을 수행하는 ObjectDataSource 컨트롤을 보여 줍니다. ObjectDataSource 컨트롤은 NorthwindEmployee 클래스의 인스턴스를 업데이트 메서드에 전달하도록 구성되어 있습니다.

<asp:objectdatasource
  runat="server"
  id="ObjectDataSource1"
  typename="EmployeeLogic"
  selectmethod="GetAllEmployees"
  updatemethod="UpdateEmployeeInfo"
  dataobjecttypename="NorthwindEmployee" />

복합 매개 변수 형식이 여러 개 포함된 매개 변수 목록을 비즈니스 개체 메서드에 사용할 경우도 있습니다. 이런 경우에는 ObjectDataSource 컨트롤을 사용할 수 있지만 매개 변수를 프로그래밍 방식으로 ObjectDataSource 컨트롤에 추가해야 합니다. 이렇게 하려면 Inserting, Updating 또는 Deleting 이벤트처럼 데이터 작업이 수행되기 전에 발생하는 이벤트를 처리하고, ObjectDataSourceMethodEventArgs 클래스에 의해 노출되는 InputParameters 컬렉션에서 값을 설정합니다.

표시: