65.9K
CodeProject is changing. Read more.
Home

Dynamic Sorting in LINQ

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (6 votes)

Oct 8, 2013

CPOL
viewsIcon

24040

Dynamically sort query results using LINQ expressions and reflection.

Introduction

When developing data-driven applications there comes a point when data is to be displayed in a tabular format, such as a data-bound grid or other such control interface.  These interfaces can provide a means of sorting the data they contain while leaving the responsibility of how the sorting operation is performed up to the developer.  In this tip, we're going to take a look at how to dynamically set the sorting property of a collection to the OrderBy extension method. 

Using the code 

We begin with defining a basic data class, in this case a managed list of strings:  

public class SampleDataSource 
{
    private List<string> words = new List<string>() {
        "the",
        "quick",
        "red",
        "fox",
        "jumped",
        "over",
        "the",
        "lazy",
        "brown",
        "dog"
    };

    public IEnumerable<string> GetWords() 
    {
        return GetWords(null);
    }

    public IEnumerable<string> GetWords(string sortPropertyName) 
    {
        if (!String.IsNullOrEmpty(sortPropertyName)) {
            PropertyInfo pinfo = typeof(string).GetProperty(sortPropertyName);
            if (pinfo != null) {
                return words.OrderBy(s => pinfo.GetValue(s, null));
            }
        }

        return words;
    }
}
Public Class SampleDataSource
    Private words As List(Of String) = New List(Of String) From {
        "the",
        "quick",
        "red",
        "fox",
        "jumped",
        "over",
        "the",
        "lazy",
        "brown",
        "dog"
    }
    
    Public Function GetWords(Optional ByVal sortPropertyName As String) As IEnumerable(Of String)
        If (String.IsNullOrEmpty(sortPropertyName) = False) Then
            
            Dim pinfo As PropertyInfo = GetType(String).GetProperty(sortPropertyName)
            
            If (pinfo IsNot Nothing) Then
                Return words.OrderBy(Function(s) pinfo.GetValue(s, Nothing))
            End If
            
        End If
        
        Return words
    End Function
End Class  

The System.String class only has one viable property that can be used for sorting in this manner, Length.  So we will create a console application that retrieves the list from the data class in its current order, then retrieves the list sorted by the length of the elements: 

public static class Program
{
    public static void Main() 
    {
        SampleDataSource dataSource = new SampleDataSource();
        IEnumerable<string> words = dataSource.GetWords();
        
        Console.WriteLine(String.Join("\n", words.ToArray()));
        
        words = dataSource.GetWords("Length");
        Console.WriteLine(String.Join("\n", words.ToArray()));
    }
}
Public Class Program
    Public Sub Main()
        Dim dataSource As SampleDataSource = New SampleDataSource()
        Dim words As IEnumerable(Of String) = dataSource.GetWords()
        
        Console.WriteLine(String.Join(Environment.NewLine, words.ToArray()))
        
        words = dataSource.GetWords("Length")
        Console.WriteLine(String.Join(Environment.NewLine, words.ToArray()))
    End Sub
End Class 

In a future tip, we'll take a look at how to dynamically set the sort direction of the resulting collection.