Aug 25 2011

Dynamic Lambda Expression For Sorting A List / Collection Using Complex Types Without Implementing IComparable

Category: .net,ASP.net,Lambda,LINQJebarson Jebamony @ 8:08 am

You can download the sample project for the article here. ComplexLinqSort.zip (259.64 kb)

In my previous post we discussed on sorting the list / collection using dynamic lambda expression for properties. In this article we will see how to sort on complex properties.

So what is a complex property. Consider the class diagram as shown below

 

In our scenario, we have “Employee” entity, where we have a property “Department” which is a complex type. Now let us assume that we are binding the list of employees list along with the department name, then we will have to use item template along with “Bind” method called.

 

In the above sample we have the department name displayed which is obviously shown as the below tag.

<asp:TemplateField HeaderText="Department" SortExpression="Department.Name">
   <ItemTemplate>
       <asp:Label ID="DepartmentName" Text='<# Bind("Department.Name") >' runat="server" />
    </ItemTemplate>
</asp:TemplateField>

While you are sorting, since the sort expression is set to “Department.Name”, on the sorting event you will get the sort expression as the same. Now if you want to get the sorting done, then you will need to implement the IComparable interface. However, lets see a simple solution which will get us the same job done with the help of lambda expression.

        private Expression<Func<Employee, object>> GetPropertyExpression(string sortColumn)
        {
            // Prepare the dynamic sort expression
            Expression propConvExp;
            var paramExp = Expression.Parameter(typeof(Employee), typeof(Employee).ToString());

            if (sortColumn.Contains('.'))
            {
                string[] keys = sortColumn.Split('.');

                propConvExp = Expression.Property(paramExp, keys[0]);

                for (int index = 1; index < keys.Length; index++)
                {
                    propConvExp = Expression.Property(propConvExp, keys[index]);
                }

                propConvExp = Expression.Convert(propConvExp, typeof(object));
            }
            else
            {
                propConvExp = Expression.Convert(Expression.Property(paramExp, sortColumn), typeof(object));
            }

            Type propertyType = propConvExp.Type;

            return  Expression<Func<Employee, object>>(propConvExp, paramExp);
        }

The above method generates the expression for the property we give as the string seperated by “.” (period). The final property expression will be the dynamic lambda expression of the complex type we are sending. You can convert the same to use the generic type “T” instead of “Employee” so that you dont have to write seperate methods for every class.

The sorting can be done based on department name as below.

this.Employees.AsQueryable().OrderByDescending(this.GetPropertyExpression(e.SortExpression)).ToList();

You can download the sample project for the same here ComplexLinqSort.zip (259.64 kb)

3 Responses to “Dynamic Lambda Expression For Sorting A List / Collection Using Complex Types Without Implementing IComparable”

  1. kaio074 says:

    In some case this function return me this error: “Unable to cast the type ‘System.String’ to type ‘System.Object’. LINQ to Entities only supports casting Entity Data Model primitive types.” I notice that the instruction Type propertyType = propConvExp.Type; assign only a value to propertyType variable but it is not used anywhere. Thanks

  2. Jebarson says:

    Kaio you would need to do a conversion of the expression to sort it out.

  3. Luis Fernando says:

    I came here to thank you for sharing this code, is of great value to me.
    Although I’m not used to sort, but to group.
    And I’ll try to make an adjustment to filter as well.

    Happy new year!

Leave a Reply