Сортировка в GridView

ASP.NET   1 октября 2012  Автор статьи:  

GridView умеет сортировать по нажатию на заголовок столбца. В данной статье, я рассмотрю как сделать это с использованием ObjectDataSource и SQLDataSource. Итак, приступим. Создадим пустой проект ASP.NET, в нем создадим базу данных, в которой у нас будет одна таблица, которую мы будем выводить и пытаться всячески сортировать. Пусть в этой таблице для начала будет три столбца: ID, Name и Age. ID — будет автоинкрементным ключом(int), Name (nvarchar(MAX)) и Age (int). Назовем данную базу данных TestBase, а таблицу SortedTable. Данную базу я поместил в папочку App_Data, которая находится в самом проекте. Необходимо наполнить ее тестовыми данными, чтобы нам с вами было, что отображать. Более подробно о создании баз данных вы можете прочитать здесь. Следующим шагом нужно добавить строку подключения в файл. Для подробного ознакомления с этой темой, вы можете воспользоваться официальной документацией сервера баз данных, который вы хотите использовать, или просмотреть статью «Подключение к базе данных». Если у вас не получилось создать подключения, то тогда я могу вам предложить еще один способ создания подключения. После создания базы данных и работы с ней, данные о подключении можно выдрать в правом нижнем окошке, в строке «строка подключения».
Оно откроется, если вы выберите соответствующее подключение.
После этого требуется создать страницу, на которой мы разместим элемент управления GridView. Я создам Web Form и назову ее Default.aspx. Кину на нее GridView и с помощью конструктора выберу для нее источник данных. Пусть вначале это будет SQLDataSource, тогда выполнив пару тривиальных шагов вы сможете подключиться к базе данных, и отображать информацию о ней. В режиме конструктора теперь вы сможете выбрать галку сортировать. Прилагаю код страницы, если у вас что — то не получилось:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GridViewSort.Default" %>











SelectCommand="SELECT * FROM [SortedTable]">




Теперь попробуем отсортировать нашу таблицу с помощью ObjectDataSource. Создадим класс User.cs, который будет прототипом записи в таблице SortedTable.

public class User
{
public int ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}

Теперь создадим бизнес логику для объекта User. Сделаем этот код достаточно простым, реализуем метод GetAll(string sortExpression), который будем возвращать коллекцию пользователей:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Reflection;
using System.Linq.Expressions;
using System.Data.SqlClient;
using System.Text;
using System.Web.Configuration;

namespace GridViewSort
{
public class Class1
{
public static Func GetValueGetter(string name)
{
PropertyInfo propertyInfo = typeof(V).GetProperty(name);
ParameterExpression instance = Expression.Parameter(typeof(V), "i");
UnaryExpression castedInstance = Expression.ConvertChecked(instance, propertyInfo.DeclaringType);
MemberExpression property = Expression.Property(castedInstance, propertyInfo);
UnaryExpression convert = Expression.Convert(property, typeof(T));
LambdaExpression expression = Expression.Lambda(convert, instance);
return (Func)expression.Compile();
}
public IList GetAll(string sortExpression)
{

string connectionString = WebConfigurationManager.ConnectionStrings["ourBase"].ConnectionString;
SqlConnection con = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand("SELECT * FROM SortedTable", con);
con.Open();
SqlDataReader reader = command.ExecuteReader();
StringBuilder s = new StringBuilder();//генерируем текст для вывода
IList users = new List();

while (reader.Read())
{
users.Add(new User()
{
ID = (int)reader.GetValue(0),
Name = (string)reader.GetValue(1),
Age = (int)reader.GetValue(2)
});
}
if (sortExpression.Length == 0)
{
return users;
}
Func sortLambda;
if (sortExpression.Split(' ').Length == 2)
{
string newSortExpression = sortExpression.Split(' ')[0];
sortLambda = GetValueGetter(newSortExpression);
return users.OrderByDescending(sortLambda).ToList();
}
sortLambda = GetValueGetter(sortExpression);
return users.OrderBy(sortLambda).ToList();
}
}
}

Данный код достаточно трудно прокомментировать новичку, так как тут использованы как лямбда выражения, так и рефлексия, но общий смысл такой, мы пишем метод GetAll, который принимает на вход название столбца по которому сортируем, и если сортируем этот столбец в обратном порядке, то добавляется слово Desc, после этого мы достаем все элементы из коллекции. Затем мы получаем лямбда выражение для сортировки и сортируем по возрастанию или убыванию с помощью LINQ. Данный код очень гибок, в том плане, что он рассчитан на то, что бизнес логика может быть легко отделена от кода. Теперь рассмотрим как можно было избавиться от рефлексии и лямбда выражений, передавая в SQL — запрос название столбца, данный способ не рекомендуется к использованию в реальных программах, так как вам могут потенциально просунуть SQL- Injection:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Reflection;
using System.Linq.Expressions;
using System.Data.SqlClient;
using System.Text;
using System.Web.Configuration;

namespace GridViewSort
{
public class Class1
{
public IList GetAll(string sortExpression)
{

string connectionString = WebConfigurationManager.ConnectionStrings["ourBase"].ConnectionString;
SqlConnection con = new SqlConnection(connectionString);
SqlCommand command;
if (sortExpression.Length == 0)
{
command = new SqlCommand("SELECT * FROM SortedTable", con);
}
else command = new SqlCommand("SELECT * FROM SortedTable ORDER BY " + sortExpression, con);
con.Open();
SqlDataReader reader = command.ExecuteReader();
StringBuilder s = new StringBuilder();//генерируем текст для вывода
IList users = new List();

while (reader.Read())
{
users.Add(new User()
{
ID = (int)reader.GetValue(0),
Name = (string)reader.GetValue(1),
Age = (int)reader.GetValue(2)
});
}
return users;
}
}
}

Теперь после создания кода бизнес логики, достаточно в элементе GridView разрешить сортировку AllowSorting=»true». И сказать имя переменной, по которой будет сортироваться наша таблица в ObjectDataSource:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GridViewSort.Default" %>


















Если вам не нужно поддерживать свой пользовательский класс, как мы это делали, то тогда возвращайте DataSet или DataTable, они поддерживают сортировку по умолчанию, тогда вам не придется писать метод, который будет принимать на вход название столбца.

Научиться программировать

  • на Delphi

  • на Java

  • на C++