다음을 통해 공유


데이터 소스 컨트롤을 사용한 데이터 정렬

업데이트: 2007년 11월

데이터 소스 컨트롤과 데이터 바인딩된 컨트롤을 사용하여 ASP.NET 웹 페이지에 데이터를 표시할 수 있습니다. 일부 데이터 컨트롤은 사용자가 코드 없이도 데이터를 정렬할 수 있게 해 줍니다.

사용자가 런타임에 코드를 정렬할 수 있게 하려면 LinqDataSource, ObjectDataSource, SqlDataSource 또는 AccessDataSource 컨트롤을 데이터 소스 컨트롤로 사용하면 됩니다. 사용자가 정렬할 수 있는 데이터를 표시하려면 GridView 컨트롤이나 ListView 컨트롤을 사용합니다.

정렬용 사용자 인터페이스 제공

정렬을 위한 UI(사용자 인터페이스)를 만들 수 있습니다. 그러나 GridViewListView 컨트롤은 기본 UI 정렬을 제공합니다.

GridView 컨트롤에서는 프로그래밍하지 않고도 단일 열을 기준으로 한 정렬을 지원합니다. 정렬 식을 데이터 소스 컨트롤로 전달하는 링크 단추로 각 열의 머리글 텍스트를 자동으로 만들려면 AllowSorting 속성을 true로 설정합니다. 정렬 이벤트 처리를 통해 GridView 컨트롤의 정렬 기능을 추가로 사용자 지정할 수 있습니다. 자세한 내용은 GridView 웹 서버 컨트롤의 데이터 정렬을 참조하십시오.

컨트롤의 LayoutTemplate 템플릿에 단추를 추가하고 단추의 CommandName 속성을 "Sort"로 설정하여 ListView 컨트롤에 표시되는 데이터를 정렬할 수 있습니다. 단추의 CommandArgument 속성은 정렬할 열 이름으로 설정합니다. 정렬 단추를 클릭하면 정렬 방향이 AscendingDescending 사이에서 전환됩니다. 자세한 내용은 ListView 웹 서버 컨트롤 개요연습: ListView 웹 서버 컨트롤을 사용하여 데이터 표시, 페이징 및 정렬을 참조하십시오.

데이터 소스 컨트롤에서 정렬 사용

정렬이 기본적으로 지원되는 데이터 소스 컨트롤에는 LinqDataSource, ObjectDataSource, SqlDataSourceAccessDataSource 컨트롤이 있습니다. LinqDataSource 컨트롤은 다음 예제와 같이 AutoSort 속성이 true(기본값)로 설정된 경우 정렬을 지원합니다.

<asp:LinqDataSource 
    ContextTypeName="ExampleDataContext" 
    TableName="Products" 
    AutoPage="true"
    AutoSort="true"
    ID="LinqDataSource1" 
    >
</asp:LinqDataSource>
<asp:GridView 
    AllowPaging="true"
    AllowSorting="true"
    DataSourceID="LinqDataSource1"
    ID="GridView1" 
    >
</asp:GridView>
<asp:LinqDataSource 
    ContextTypeName="ExampleDataContext" 
    TableName="Products" 
    AutoPage="true"
    AutoSort="true"
    ID="LinqDataSource1" 
    >
</asp:LinqDataSource>
<asp:GridView 
    AllowPaging="true"
    AllowSorting="true"
    DataSourceID="LinqDataSource1"
    ID="GridView1" 
    >
</asp:GridView>

SqlDataSourceAccessDataSource 컨트롤은 다음 예제와 같이 DataSourceMode 속성이 DataSet(기본값)으로 설정된 경우에만 정렬을 지원합니다.

<asp:GridView ID="EmployeesGridView" 
  DataSourceID="EmployeesSqlDataSource" 
  DataKeyNames="EmployeeID" 
  AllowSorting="True"
  RunAt="Server" />

<asp:SqlDataSource ID="EmployeesSqlDataSource"  
  SelectCommand="SELECT EmployeeID, LastName, FirstName FROM Employees" 
  Connectionstring="<%$ ConnectionStrings:NorthwindConnectionString %>" 
  RunAt="server" />
<asp:GridView ID="EmployeesGridView" 
  DataSourceID="EmployeesSqlDataSource" 
  DataKeyNames="EmployeeID" 
  AllowSorting="True"
  RunAt="Server" />

<asp:SqlDataSource ID="EmployeesSqlDataSource"  
  SelectCommand="SELECT EmployeeID, LastName, FirstName FROM Employees" 
  Connectionstring="<%$ ConnectionStrings:NorthwindConnectionString %>" 
  RunAt="server" />

ObjectDataSource 컨트롤은 SelectMethod에서 반환하는 개체가 DataSet, DataTable 또는 DataView 개체인 경우에 정렬을 지원합니다. 또한 ObjectDataSource는 데이터 소스에서 정렬된 순서대로 결과를 검색하는 기능도 지원합니다.

사용자 지정 정렬

데이터 바인딩된 컨트롤 및 데이터 소스 컨트롤에 의해 정렬이 수행되는 방식을 사용자 지정하면 자동 정렬이 수행되는 방식을 수정하거나 사용자 지정 정렬 루틴을 만들 수 있습니다.

LinqDataSource 컨트롤을 사용하는 경우 AutoSort 속성을 false로 설정하여 정렬을 사용자 지정할 수 있습니다. 그리고 나서 Selecting 이벤트에 대한 이벤트 처리기를 만들 수 있습니다.

ObjectDataSource 또는 SqlDataSource 컨트롤을 사용하는 경우 SortParameterName 속성을 사용하여 정렬 기능을 활용할 수 있습니다. SortParameterName 속성에는 데이터 소스 컨트롤에 전달하는 정렬 식이 포함된 매개 변수의 이름을 설정할 수 있습니다. 정렬 식은 정렬 기준으로 사용할 필드의 쉼표로 구분된 목록입니다. 내림차순으로 정렬하려면 DESC 식별자도 포함할 수 있습니다. 정렬 식의 형식에 대한 자세한 내용은 DataView.Sort 속성을 참조하십시오.

SortParameterName 속성에 의해 식별되는 매개 변수는 ObjectDataSource 컨트롤의 SelectMethod에 전달되거나 SqlDataSource 컨트롤의 SelectCommand에 매개 변수 컬렉션의 일부로 전달됩니다. ObjectDataSource 컨트롤은 정렬 매개 변수에서 전달된 정보를 사용하여 정렬된 순서로 데이터를 반환할 수 있습니다. SqlDataSource 컨트롤의 경우에는 ORDER BY 절의 일부로 매개 변수를 전달할 수 없으므로 정렬 매개 변수를 사용하고 정렬된 데이터를 반환할 수 있는 저장 프로시저의 이름을 제공해야 합니다.

다음 코드 예제에서는 sortColumns라는 매개 변수를 정렬 매개 변수 이름으로 식별하는 ObjectDataSource 컨트롤 선언을 보여 줍니다.

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

다음 코드 예제에서는 ObjectDataSource 컨트롤에 대한 소스 개체의 메서드를 보여 줍니다. 이 메서드는 SelectMethod로 식별됩니다. SortParameterName 속성에 의해 식별되는 매개 변수는 데이터베이스에서 검색된 데이터를 정렬하는 데 사용됩니다.

Public Shared Sub Initialize()    
  ' Initialize data source. Use "Northwind" connection string from configuration.

  If ConfigurationManager.ConnectionStrings("Northwind") Is Nothing OrElse _
     ConfigurationManager.ConnectionStrings("Northwind").ConnectionString.Trim() = "" Then      
    Throw New Exception("A connection string named 'Northwind' with a valid connection string " & _
                        "must exist in the <connectionStrings> configuration section for the application.")
  End If

  _connectionString = _
    ConfigurationManager.ConnectionStrings("Northwind").ConnectionString

  _initialized = True
End Sub



' Select all employees.

<DataObjectMethod(DataObjectMethodType.Select, True)> _
Public Shared Function GetAllEmployees(sortColumns As String, startRecord As Integer, maxRecords As Integer) As DataTable

  VerifySortColumns(sortColumns)

  If Not _initialized Then Initialize()

  Dim sqlCommand As String = "SELECT EmployeeID, LastName, FirstName, Address, City, Region, PostalCode FROM Employees "

  If sortColumns.Trim() = "" Then
    sqlCommand &= "ORDER BY EmployeeID"
  Else
    sqlCommand &= "ORDER BY " & sortColumns
  End If

  Dim conn As SqlConnection  = New SqlConnection(_connectionString)
  Dim da   As SqlDataAdapter = New SqlDataAdapter(sqlCommand, conn) 

  Dim ds As DataSet =  New DataSet() 

  Try
    conn.Open()
    da.Fill(ds, startRecord, maxRecords, "Employees")
  Catch e As SqlException
    ' Handle exception.
  Finally      
    conn.Close()
  End Try

  If ds.Tables("Employees") IsNot Nothing Then _
    Return ds.Tables("Employees")

  Return Nothing
End Function


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

Private Shared Sub VerifySortColumns(sortColumns As String)

  If sortColumns.ToLowerInvariant().EndsWith(" desc") Then _
    sortColumns = sortColumns.Substring(0, sortColumns.Length - 5)

  Dim columnNames() As String = sortColumns.Split(",")

  For Each columnName As String In columnNames      
    Select Case columnName.Trim().ToLowerInvariant()        
      Case "employeeid"
      Case "lastname"
      Case "firstname"
      Case ""
      Case Else
        Throw New ArgumentException("SortColumns contains an invalid column name.")
    End Select
  Next
End Sub
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 컨트롤 소스 개체 만들기를 참조하십시오.

참고 항목

기타 리소스

데이터 소스 웹 서버 컨트롤