Business Objects (the list) is sorted based on

Sort object-based business

introduction

In the previous article screening based on the business object , we discussed how to implement Predicate <T> (T object) commissioned a custom DateFilter class to filter the business objects. Like the screening, sorting is a common and important operation. When sorting business objects can not be used as a data source ObjectDataSource, because it only supports automatic sorting DataView, DataTable and DataSet. But you can still write processing method for the Sorting event of GridView, assembled by the SQL statement, using the "Order By" clause to complete the order.

And screening ideas, like if we will business objects cached on the server, the first visit to extract data from the database, and then cached, subsequent requests are cached for only the business object, you can reduce dependence on database ,Improve efficiency. This article will discuss how to get the sort of business objects, including a simple sort any column sorting, complex and multi-column sorting.

NOTE : This article is written by then on a number of duplicate content will no longer be about the article, it is recommended to read based screening business objects .

Simple Sort - sort of default fixed property

And on different articles, I no longer explain ways to use SQL to complete the assembly of the sort we see based on the direct sequencing List <Order> object. We know that List <T> provides the Sort () method to sort the operation, then how do you use it? Let's create a ObjSort.aspx file, and then add the following code in the code-behind:

protected void Page_Load(object sender, EventArgs e)
 {
     Label lb1 = new Label();

     List<int> list = new List<int>();
     list.Add(4);
     list.Add(5);
     list.Add(2);
     list.Add(9);
     list.Add(1);

     foreach (int item in list) {
        lb1.Text += item.ToString() + ", ";
     }

     form1.Controls.Add(lb1);
     HtmlGenericControl hr = new HtmlGenericControl("hr");
     form1.Controls.Add(hr);

     Label lb2 = new Label();
     list.Sort();     // 对列表进行排序
     foreach (int item in list) {
        lb2.Text += item.ToString() + ", ";
     }
     form1.Controls.Add(lb2);
 }

It can be seen by using the List <int> Sort () method, the elements of the list are sorted. Now we added a new one in OrderManager.cs method GetSortList (), which is used to obtain a list of objects, because too many record number GetList () method returns, and in this paper we focus only sort, so we only returned 15 records .

// 获取用于排序的列表
public static List<Order> GetSortList() {

    List<Order> list = HttpContext.Current.Cache["sortList"] as List<Order>;

    if (list == null) {
       list = GetList("Select Top 15 OrderId, CustomerId, ShipCountry, OrderDate From Orders");
       HttpContext.Current.Cache.Insert("sortList", list);
    }

    return list;
}

If you do not fancy an article, then just know that this method returns a List <Order> type of business object that represents a list of orders on it (Order object contains four public properties, which are OrderId, CustomerId, OrderDate, Country ). Then we create ObjSort2.aspx file, drag and drop it on top of a Reperter control, and write some code for displaying a table:

<asp:Repeater runat="server" ID="rpOrderList" >
    <HeaderTemplate>
     <table>
        <tr>
            <th>
               <asp:LinkButton ID="lbtOrderId" runat="server">OrderId</asp:LinkButton>
            </th>
            <th>
               <asp:LinkButton ID="lbtCustomerId" runat="server">CustomerId</asp:LinkButton>
            </th>
            <th>
               <asp:LinkButton ID="lbtOrderDate" runat="server">OrderDate</asp:LinkButton>
            </th>
             <th>
                <asp:LinkButton ID="lbtCountry" runat="server">Country</asp:LinkButton>
            </th>
        </tr>
    </HeaderTemplate>
    <ItemTemplate>
        <tr>
            <td><%#Eval("OrderId") %></td>
            <td><%#Eval("CustomerId") %></td>
            <td><%#Eval("OrderDate") %></td>
             <td><%#Eval("Country") %></td>
        </tr>
    </ItemTemplate>      
    <FooterTemplate>     
     </table>
    </FooterTemplate>    
 </asp:Repeater>

Then, we Page_Load event in the code behind ObjSort2.aspx.cs, add this two-line statement:

rpOrderList.DataSource = OrderManager.GetSortList();
rpOrderList.DataBind();

And then turn the page, you can see a list of output on the page. Now we want to sort this list, then we modeled List <int> practice, modify the code above:

List <the Order> = OrderManager.GetSortList List ();
list.sort (); // can sort desired
rpOrderList.DataSource = List;
rpOrderList.DataBind ();

In fact, we get an error: You must have at least an object implements IComparable.

IComparable <T> Interface

We should think that they want to be wrong Why: Order object contains four property OrderId, CustomerId, OrderDate, Country, and only int value of its own, so when we call the Sort () on the List <Order> time , list of objects that do not know how to sort, do not know what to attribute to sort. The IComparable interface defines the rules for how to sort, if we want to List <Order> objects are sorted, then we need to make a list of elements, ie Order object that implements this interface. In fact, List <int> The reason why you can call Sort () method directly, because int, and almost all of the basic types (such as string, char, datetime, etc.), itself implements IComparable <T>.

public interface IComparable<T> {
    int CompareTo(T other);
}

This interface need only implement a method, CompareTo (), passing it the object (the current object list) to be compared with the same type of another object other, the return value of type int: the current object is less than zero is less than other parameters. This object is equal to zero other. Greater than zero current object is greater than the other.

Now we let the Order object (see Download Order code) implements this interface:

// 实现 IComparable<T> 接口
public int CompareTo(Order other) {
    return this.CustomerId.CompareTo(other.CustomerId);
}

We will sort rules entrusted to CustomerId to deal with, because CustomerId is a string type, called its CompareTo () method. In this way, the List <Order> calling Sort () time will be according to the rules defined here to sort the CustomerId. Open ObjSort.aspx again, you should see a list sorted by CustomerId.

Advanced Sort - Sort multiple properties combined

IComparer <T> Interface

The above list is just to provide a default sort, in fact, we often require multiple columns are sorted, we will be asked to sort in ascending or descending order, we even asked for combining multiple columns to sort, such as: CustomerId ascending order of the first, and then the OrderDate descending order. At this time, although CompareTo (Order other) can be achieved, but to give additional fields Order object or attribute that .Net Framewok been taken into account, and provides IComparer <T> interface package sorting rules, we can implement this interface to complete the order.

public interface IComparer<T> {
    int Compare(T x, T y);
}

IComparer <T> need only implement a method, the Compare () which accepts two parameters of the same type, and returns a result of type int, and the like IComparable <T>, when the return value is less than 0, x is less than Y; equal to zero , x is equal to Y; greater than 0, x is greater than y. Note that: This interface requires that we not let the Order object to achieve it, but requires another object to achieve it, such as OrderComparer, while calling Sort () method when, it will be passed as parameters. Because this OrderComparer only used to sort the Order object, it can not be applied to other objects, so we will declare it as Order of nested class.

Achieve IComparer <T> Interface

Order.cs open file, it modified as follows, to add an enumeration the SortDirection, for sorting direction represents:

// reusable enumeration indicating direction of the sort
public enum {the SortDirection
    Ascending = 0,
    Descending
}

Order within the class, add an enumeration, enumeration types represent attributes can be sorted:

// nested enumeration, applied only to this business object, the sort attributes available
public enum {the SortField
    the OrderId,
    the CustomerId,
    the OrderDate,
    Country
}

We still need to define a structure Sorter, this structure contains two fields, a SortDirection type, a type SortField, which encapsulates the necessary information for the order: for which property (ascending or descending order) by which way. Due to this structure it remains only for the Order object, so we define it within the Order:

// nested structure, applied only to this business object, the sorting properties and methods
public struct {Sorter
    public the SortField Field;
    public the SortDirection direction;

    public Sorter (the SortField Field, the SortDirection direction) {
       this.field = Field;
       this.direction = direction;
    }

    public Sorter (the SortField Field) {
       this.field = Field;
       this.direction = SortDirection.Ascending;
    }
}

Next, we achieve IComparer <T> class is defined within OrderComparer Order:

// nested classes, only this sort of business objects
public class OrderComparer: the IComparer <the Order> {

}

Now consider how to achieve it: because we want to achieve, sort of a property in a certain way, then we at least want to pass in these two parameters, so OrderCompare should contain fields for maintenance SortDirection and SortField; because we can expect sorting the plurality of attribute combinations, it should maintain a list of them, and the SortDirection SortFiled, Sorter already included in the structure, so long as it maintains a list <Sorter> structure can be:

OrderComparer class public: the IComparer <the Order> {
    Private List <Sorter> List;
    // constructor, setting list of sort fields
    public OrderComparer (List <Sorter> List) {
        This.List = List;
    }
}

Then think about how to sort, start with a simple start, we do not consider ordering for multiple properties, just sort of a property in a certain way, then we need to add a method CompareTo (), which accepts the sort of property, sort of way , and ordered the two objects, and returns an int, indicating both the size of the object (has locations):

// the individual attributes in some way to sort
public int the Compare (the Order X, Y the Order, the SortField Field, the SortDirection direction) {
    int Result = 0; // default sort position does not change

    Switch (Field) {
       Case SortField.Country:
           IF (direction == SortDirection.Ascending)
              Result = x.Country.CompareTo (y.Country);
           the else
              Result = y.Country.CompareTo (x.Country);
           BREAK;
       Case SortField.CustomerId:
           IF (the SortDirection == direction. Ascending)
              Result = x.CustomerId.CompareTo (y.CustomerId);
           the else
              Result = y.CustomerId.CompareTo (x.CustomerId);
           BREAK;
       case SortField.OrderDate:
           if (direction == SortDirection.Ascending)
              result = x.OrderDate.CompareTo(y.OrderDate);
           else
              result = y.OrderDate.CompareTo(x.OrderDate);
           break;
       case SortField.OrderId:
           if (direction == SortDirection.Ascending)
              result = x.OrderId.CompareTo(y.OrderId);
           else
              result = y.OrderId.CompareTo(x.OrderId);
           break;
    }

    return result;
}

However, this method does not achieve IComparer <T> interfaces, there is no way to sort the plurality of columns. Before proceeding, we consider how the two properties of a plurality of objects (such as A, B, C) be ordered: A first property to be compared, and if the same attribute A, B continue to compare attributes, the same attribute if B, C. continue to compare properties In this process, as long as there is not the same as any one property, can determine the order of the two objects, that is no longer attribute later comparison.

With ideas, we now realize IComparer <T> interface method for the preparation of

// implement the IComparer interface
public int the Compare (the Order X, Y the Order) {
    int Result = 0;
    the foreach (Sorter in Item List) {
       Result = the Compare (X, Y, item.field, item.direction);
       IF (Result! = 0) // Once the result is not 0, the size of the position have been distinguished, out of the loop
           BREAK;
    }

    return result;
}

In this method, we traverse the List <Sorter>, and is called comparative method Compare individual attribute we defined above (Order x, Order y, SortField field, SortDirection direction) in foreach statement, once the comparison result is not 0, then out of the loop.

Well realization OrderComparer class has been completed, what else can we look at the perfect place: If after every call Sort to sort the time, must first need to create a list, specify a collation, construction OrderCompare objects, apparently will be difficult, so we have to add a set of overloaded methods GetComparer in the Book class (), to simplify the procedure when the call later:

// Specify ordering properties and sort
public static OrderComparer GetComparer (the SortField Field, the SortDirection direction) {
    List <Sorter> = new new List List <Sorter> ();
    Sorter Sorter = new new Sorter (Field, direction);
    list.add (Sorter );
    return new new OrderComparer (List);
}

// sort attribute specified, the default is ascending
public static OrderComparer GetComparer (the SortField Field) {
    return new new OrderComparer (Field, SortDirection.Ascending);
}

// defaults to ascending OrderId
public static GetComparer OrderComparer () {
    return new new OrderComparer (SortField.OrderId, SortDirection.Ascending);
}

// Sort the list
public static OrderComparer GetComparer (list <Sorter > list) {
    return new OrderComparer(list);
}

Well, now OrderComparer class on all created, we are going to look at how to use it:

Page calls

We modify the code behind file, look at how to set up, we will Sort () change it to this:

list.Sort (Order.GetComparer (Order.SortField.Country, SortDirection.Descending)); // in reverse order Country

Then view the page, find the list of attributes to Country reverse order. What if we want to press Country reverse order, then CustomerId order, how?

// Country descending order, CustomerId ascending
List <Order.Sorter> sorterList = new List <Order.Sorter> (); // create sorterList
sorterList.Add (new new Order.Sorter (Order.SortField.Country, SortDirection.Descending )); // first ordered in Asc Country
sorterList.Add (new new Order.Sorter (Order.SortField.CustomerId)); // Asc again to CustomerId
list.sort (Order.GetComparer (sorterList));

Now open the page, you can see a list of the way we expect to be sorted. In this context, due merely for illustrative purposes, so we write directly for the SortList sort of code, in fact, these should be based on the user to select and dynamically created. On ObjSort2.aspx page, the title of the table I use the LinkButton, are interested, you can write LinkButton Click event to achieve this sort of dynamic process.

to sum up

This paper discusses how the list (business objects) to be sorted.

We first understand the IComparable <T> interface to learn how to implement this interface in order to achieve a default sort for a field. Next, we discuss in detail how to implement a IComparer <T> interface may be implemented on any single sort attribute, and a plurality of combinations of attributes.

As you can see, once you master the method later, and then write the code OrderComparer such as this is boring, then we'll take a look if the use of reflection to write a small program to automatically generate the code for us.

Thanks for reading, I hope this article can give you help.

Reproduced in: https: //www.cnblogs.com/JimmyZhang/archive/2008/03/18/1110710.html

Guess you like

Origin blog.csdn.net/weixin_33834137/article/details/93444068