RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


The Baker's Dozen: 13 Steps for Building an ASP.NET Database Lookup Page : Page 7

Build a database search Web page using new features in ASP.NET 2.0, SQL Server 2005, and .NET generics in C#.

Bonus: The Baker's Dozen Potpourri: Sorting Custom Lists with Anonymous Methods
I'm still a DataSet guy—although I admit that the capabilities of the .NET generics List class are powerful, especially when combined with the new anonymous methods in C# 2.0. This Baker's Dozen Potpourri will present some code snippets for sorting and filtering custom list collections.

For example, I have a list of records with LocationID, Customer ID, and Amount Due fields, and I want to filter on Locations 1 and 2, where the Amount Due is greater than 10000. I also want to sort the results on Amount Due descending, within Location. If I use ADO.NET, I can accomplish this with a DataView, as follows:

   DataView dv = new DataView(dt);
   dv.RowFilter =
      "LocationID in (1,2) AND AmountDue > 10000";
   dv.Sort = "LocationID, AmountDue DESC"; 
In the "DataSets vs. custom collections" debate, proponents of DataSets argue that you'd have to write more complicated code to achieve the same functionality with custom collections. (I certainly made that argument prior to Visual Studio 2005.)

However, Visual Studio 2005 provides two new capabilities that I can combine to produce a good counterpart to the ADO.NET snippet above. First, the new List class contains methods to sort and filter (using the Sort and FindAll methods). I'll write a custom method for sorting/filtering, and specify the name of the method as a delegate parameter for the Sort/FindAll method.

Second, C# 2.0 allows developers to use anonymous methods to place logic in place of a delegate. Instead of writing a separate custom method, developers can include code inline where the delegate would otherwise appear. I'll show you some code samples to demonstrate. Instead of a DataSet, I'll take an example of a custom list called CustomerRec, with properties for LocationID and AmountDue.

The code inserts an anonymous method inside the list's FindAll method to create a filtered list of customers where LocationID equals 1. Then the code sorts the filtered list on Amount Due descending.

Note that the delegate parameter for the Sort method receives two parameters, one for each object instance as part of a sort comparison. The anonymous method code will execute for each item in the list. For each execution, the code compares the two incoming values and uses the .NET CompareTo method to return the greater of the two values. If the example called for a sort in ascending sequence, the code would compare the first parameter to the second, but since the example calls for a descending sort, the code reverses the use of the parameters.

   // anonymous method to filter on Location = 1
   List<CustomerRec> oFilteredCustomers =  
      (delegate(CustomerRec oRec)  {
      return (oRec.LocationID == 1 );})
   // anonymous method to sort on amount due DESC
   // by reversing the incoming parameters 
      delegate(CustomerRec oRec1, CustomerRec oRec2)
      { return oRec2.AmountDue.CompareTo
         (oRec1.AmountDue); });
Developers can include more complex in-line code, such as combinations of OR and AND. The next code sample duplicates the logic from the ADO.NET sample that filters the data on either Location 1 or 2, and Amount Due greater than 10000.

   // anonymous method to filter on 
   // either Location 1 or 2, AND amount due GT 10000
   List<CustomerRec> oFilteredCustomers =  
      oCustomerRecs.FindAll((delegate(CustomerRec oRec)  {
      return (
         (oRec.LocationID == 1 || oRec.LocationID == 2)
         && oRec.AmountDue > 10000); 
Finally, the last code sample shows an anonymous method to sort the filtered list on amount descending within location. The delegate receives two parameters for each incoming comparison: if the locations are equal, the code compares the amount due of the second parameter against the first. If the locations are not equal, the code compares the location ID of the first parameter against the second.

   // Now sort on amount due DESC, within Location
   // To do so, check the two incoming locations 1st
   // If they are equal, reverse the order of two
   // incoming parameters, and compare the amount due
   // [just like above]
   // If they AREN'T equal, compare the two locations
      delegate(CustomerRec oRec1, CustomerRec oRec2)
      { return oRec1.LocationID == oRec2.LocationID ?
So in the end, while the developer must write a little more code, it is now possible using the new List class to implement advanced sorting and filtering functions. In addition, the ability to either implement anonymous methods opens the door to write custom filtering beyond ADO.NET syntax (ADO.NET does not support hooks for custom filtering methods).

You can find the entire source code for this article on my Web site. For additional information, check out my blog.

Closing Thoughts
Have you ever submitted something (an article, a paper, some code, etc.) and thought of some good ideas AFTER the fact? Well, I'm the king of thinking of things afterwards. Fortunately, that's the type of thing that makes blogs valuable. Check my blog (www.TheBakersDozen.net) for follow-up tips and notes on Baker's Dozen articles…and maybe a few additional treats!

Kevin S. Goff is the founder and principal consultant of Common Ground Solutions, a consulting group that provides custom web and desktop software solutions in .NET, Visual FoxPro, SQL Server, and Crystal Reports. Kevin has been building software applications for 17 years. He has received several awards from the U.S. Department of Agriculture for systems automation. He has also received special citations from Fortune 500 companies for solutions that yielded six-figure returns on investment. He has worked in such industries as insurance, accounting, public health, real estate, publishing, advertising, manufacturing, finance, consumer packaged goods, and trade promotion. In addition, Kevin provides many forms of custom training.
Email AuthorEmail Author
Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date