TopN in Linq

This post is a short on the power of LINQ. Particularly how to get a TopN from LINQ easily.

I had the idea of including in the run summary for a piece of software I’ve been developing at work the TopN sized tables loaded, or TopN elapse times (there will be a couple of posts on this subject in the coming days). This software is using the SqlBulkCopy to load data into a Sql Server 2008 database. It’s a bit special, in that it has the following features:

  • loads each table on separate parallel thread (using the ThreadPool class) (I’ll think about using .Net 4.0 Task sometime),
  • implements the IDataReader over a tab delimited file which has the column names for the data as the first line (a header row),
  • extracts the data files from ZIP archive (this is on different threads for each of the ZIP files being processed) using the Ionic DotNet Zip Library,
  • creates the Table to load the data into, on the fly (along with the Database, and Schemas in the database),
  • uses the Enterprise Library Logging facilities (a simple rolling flat file at present – I’ll get on to using the write to a database table for logging part one day),

Anyway, I’ll post some fragments from project this over then next couple of days (or maybe a bit longer).

Back to the TopN using Linq. I think I’ll let the code speak for itself (plus a couple of strategic comments).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace LinqTopNDemo
    /// <summary>
    /// A simple little class which has the demo data
    /// </summary>
    internal class DemoData
        /// <summary>
        /// The demo name (no imagination here)
        /// </summary>
        public string Name;
        /// <summary>
        /// An integer value to do some TopN on
        /// </summary>
        public int Salary;
        /// <summary>
        /// A date filed which is also used for TopN'ing 
        /// (just to show this works for more than numbers
        /// </summary>
        public DateTime BirthDay;
        /// <summary>
        /// A quick constructor for the data holder class
        /// </summary>
        /// <param name="name"></param>
        /// <param name="salary"></param>
        /// <param name="birthday"></param>
        public DemoData(string name, int salary, DateTime birthday)
            this.Name = name;
            this.Salary = salary;
            this.BirthDay = birthday;
        /// <summary>
        /// Overload of ToString to spit out the values 
        /// Makes the demo code easier
        /// </summary>
        /// <returns></returns>
        public override string ToString()
            StringBuilder retVal = new StringBuilder();
            retVal.AppendFormat("Name = {0}, Salary = {1}, Birthday = {2}", 
                this.Name, this.Salary, this.BirthDay.ToLongDateString());
            return retVal.ToString();
    /// <summary>
    /// The main of the program
    /// </summary>
    class Program
        static void Main(string[] args)
            List<DemoData> demo = new List<DemoData>();
            // get the top 2 salaries
            var top2Salaries = demo.OrderByDescending(a => a.Salary).Take(2);
            Debug.WriteLine("Top 2 Salaries");
            foreach (var a in top2Salaries)
            // get the top 2 birth dates
            var top2Dates = demo.OrderByDescending(a => a.BirthDay).Take(2);
            Debug.WriteLine("Top2 Birthdates");
            foreach (var a in top2Dates)

         * Output: 
Top 2 Salaries
Name = Jane Doe, Salary = 15678, Birthday = Sunday, 1 June 1980
Name = John Doe, Salary = 10000, Birthday = Thursday, 31 January 1991
Top2 Birthdates
Name = Fred Nerk, Salary = 2, Birthday = Saturday, 1 December 2001
Name = John Doe, Salary = 10000, Birthday = Thursday, 31 January 1991

        /// <summary>
        /// Just populate the list with some dummy people.
        /// </summary>
        /// <param name="demo"></param>
        private static void PopulateDemoData(List<DemoData> demo)
            demo.Add(new DemoData("Fred Nerk", 2, DateTime.Parse("2001-12-01")));
            demo.Add(new DemoData("John Doe", 10000, DateTime.Parse("1991-01-31")));
            demo.Add(new DemoData("Jane Doe", 15678, DateTime.Parse("1980-06-01")));
} Tags: ,,,
Digg This

, ,

  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: