LINQ Multiple Sorting: Ordering Data by Multiple Criteria

Language Integrated Query (LINQ) provides a powerful way to query and manipulate data in .NET. One common requirement when working with data is sorting it based on multiple criteria. In this tutorial, we will explore how to use LINQ to sort data by multiple fields, also known as multi-sorting or secondary sorting.

Introduction to LINQ Sorting

Before diving into multi-sorting, let’s cover the basics of LINQ sorting. The OrderBy method is used to sort a sequence of values in ascending order. You can specify a key selector function that determines which property of the object to use for sorting.

var movies = _db.Movies.OrderBy(m => m.Name);

This code sorts the movies collection by the Name property in ascending order.

Multi-Sorting with LINQ

To sort data by multiple fields, you can chain the ThenBy method after the initial OrderBy call. The ThenBy method specifies a secondary sorting criterion that is applied when two or more items have the same value for the primary sorting criterion.

var movies = _db.Movies.OrderBy(m => m.CategoryID).ThenBy(m => m.Name);

In this example, the movies collection is first sorted by the CategoryID property, and then by the Name property. This means that all movies with the same CategoryID will be grouped together and sorted by their Name.

Query Syntax

You can also use query syntax to perform multi-sorting. The orderby keyword is used to specify the primary sorting criterion, and subsequent orderby keywords are used for secondary sorting.

var movies = from row in _db.Movies
             orderby row.CategoryID, row.Name
             select row;

This query syntax is equivalent to the method syntax example above.

Controlling Sort Order

By default, LINQ sorts data in ascending order. You can use the descending keyword to sort data in descending order. For secondary sorting criteria, you can use the ThenByDescending method.

var movies = from row in _db.Movies
             orderby row.CategoryID descending, row.Name
             select row;

This code sorts the movies collection by the CategoryID property in descending order, and then by the Name property in ascending order.

Dynamic Sorting

In some cases, you may need to dynamically specify the sorting criteria based on user input or other factors. You can use extension methods to create a flexible sorting mechanism.

public static class IQueryableExtension
{
    public static bool IsOrdered<T>(this IQueryable<T> queryable) {
        if (queryable == null) {
            throw new ArgumentNullException("queryable");
        }

        return queryable.Expression.Type == typeof(IOrderedQueryable<T>);
    }

    public static IQueryable<T> SmartOrderBy<T, TKey>(this IQueryable<T> queryable, Expression<Func<T, TKey>> keySelector) {
        if (queryable.IsOrdered()) {
            var orderedQuery = queryable as IOrderedQueryable<T>;
            return orderedQuery.ThenBy(keySelector);
        } else {
            return queryable.OrderBy(keySelector);
        }
    }

    public static IQueryable<T> SmartOrderByDescending<T, TKey>(this IQueryable<T> queryable, Expression<Func<T, TKey>> keySelector) {
        if (queryable.IsOrdered()) {
            var orderedQuery = queryable as IOrderedQueryable<T>;
            return orderedQuery.ThenByDescending(keySelector);
        } else {
            return queryable.OrderByDescending(keySelector);
        }
    }
}

These extension methods allow you to dynamically add sorting criteria to a query without worrying about whether the query is already sorted or not.

queryable.SmartOrderBy(i => i.Property1).SmartOrderByDescending(i => i.Property2);

This code adds two sorting criteria to the queryable collection: first by Property1 in ascending order, and then by Property2 in descending order.

Conclusion

In this tutorial, we have covered the basics of LINQ multi-sorting, including how to use the OrderBy and ThenBy methods to sort data by multiple fields. We have also explored query syntax and controlling sort order using the descending keyword. Additionally, we have seen how to create a flexible sorting mechanism using extension methods.

Leave a Reply

Your email address will not be published. Required fields are marked *