Поделиться через


Сортировка данных с помощью элементов управления источниками данных

Обновлен: Ноябрь 2007

Данные на веб-странице ASP.NET можно отображать с помощью элемента управления источником данных и элемента управления с привязкой данных. Некоторые элементы управления данными позволяют пользователям сортировать данные без запроса какого-либо кода.

Если нужно разрешить пользователям сортировать данные во время выполнения, можно использовать элемент управления LinqDataSource, ObjectDataSource, SqlDataSource или AccessDataSource как элемент управления источником данных. Чтобы отобразить данные, которые могут сортировать пользователи, можно использовать элемент управления GridView или ListView.

Предоставление пользовательского интерфейса для сортировки

Можно создать любой пользовательский интерфейс для сортировки. Однако элементы управления GridView и ListView предоставляют сортирующий пользовательский интерфейс по умолчанию.

Элемент управления GridView поддерживает сортировку по одному столбцу без создания дополнительного кода. Установите для свойства AllowSorting значение true для автоматического создания заголовка для каждого столбца в качестве кнопки ссылки, которая передает выражение сортировки элементу управления источника данных. Можно выполнить дальнейшую настройку функциональных возможностей сортировки элемента управления GridView путем обработки события сортировки. Дополнительные сведения см. в разделе Сортировка данных в серверном веб-элементе управления GridView.

Можно сортировать данные, отображаемые в элементе управления ListView, путем добавления кнопки к шаблону LayoutTemplate элемента управления и установкой для свойства CommandName кнопки значения «Sort». Установите для свойства CommandArgument кнопки имя столбца, по которому нужно выполнить сортировку. Нажмите кнопку «Sort», запускающую направление сортировки между Ascending и Descending. Дополнительные сведения см. в разделах Общие сведения о серверном веб-элементе управления ListView и Пошаговое руководство. Отображение, разбиения по страницам и сортировка данных с помощью серверного веб-элемента управления ListView.

Включение сортировки в элементе управления источником данных

Встроенную поддержку сортировки предоставляют элементы управления источником данных LinqDataSource, ObjectDataSource, SqlDataSource и AccessDataSource. Элемент управления LinqDataSource поддерживает сортировку, когда для свойства AutoSort установлено значение true (по умолчанию), как в следующем примере:

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

Элементы управления SqlDataSource и AccessDataSource поддерживают сортировку, только когда для их свойства 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, передается свойству SelectMethod элемента управления ObjectDataSource или передается как часть набора параметров свойству SelectCommand элемента управления SqlDataSource. Элемент управления ObjectDataSource может использовать сведения, переданные ему в параметре сортировки для возращения данных в отсортированном порядке. Для элемента управления SqlDataSource необходимо предоставить имя сохраненной процедуры, которое может принимать параметр сортировки и возвращать отсортированные данные, так как нельзя передать параметр как часть предложения ORDER BY.

В следующем примере кода показано объявление элемента управления ObjectDataSource, которое определяет параметр с именем sortColumns как имя параметра сортировки:

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

См. также

Другие ресурсы

Серверные веб-элементы управления источников данных