9

I have a method

private void BindGrid()
{
    dataContext = new VTCEntities();
    string SortExpression = "DisplayName";
    string SortDirection = "ASC";
    int skip = 0;

    if (this.ViewState["SortExp"] != null)
    {
        SortExpression = this.ViewState["SortExp"].ToString();
    }

    if (this.ViewState["SortOrder"] != null)
    {
        string d = this.ViewState["SortOrder"].ToString();
        if (d == "ASC")
        {
            SortDirection = "ASC";
        }
        else
        {
            SortDirection = "DESC";
        }
    }

    if (CurrentPage != 0)
    {
        skip = CurrentPage * PageSize;
    }

    if (SortDirection == "ASC")
    {
        this.grdCustomers.DataSource = dataContext.CustomerSet.OrderBy(i => i.DisplayName).Skip(skip).Take(PageSize);
    }
    else
    {
        this.grdCustomers.DataSource = dataContext.CustomerSet.OrderByDescending(i => i.DisplayName).Skip(skip).Take(PageSize);
    }

    this.grdCustomers.DataBind();
}

and it's starting to smell, bad. I have 4 columns that I have to sort on. I'd like to avoid doing a switch or something to determine which property on the CustomerSet I'm trying to order. What would a better programmer do to associate the SortExpression, which is a string, to the property on one of my CustomerSet objects?

Thanks as always.
Jim

1 Answer 1

12

I've used this extension method for this in the past:

public static class QueryExtensions {
    public static IQueryable<T> SortBy<T>(this IQueryable<T> source, string propertyName) {
        if (source == null) {
            throw new ArgumentNullException("source");
        }

        // DataSource control passes the sort parameter with a direction
        // if the direction is descending           
        int descIndex = propertyName.IndexOf(" DESC");

        if (descIndex >= 0) {
            propertyName = propertyName.Substring(0, descIndex).Trim();
        }

        if (String.IsNullOrEmpty(propertyName)) {
            return source;
        }

        ParameterExpression parameter = Expression.Parameter(source.ElementType, String.Empty);
        MemberExpression property = Expression.Property(parameter, propertyName);
        LambdaExpression lambda = Expression.Lambda(property, parameter);

        string methodName = (descIndex < 0) ? "OrderBy" : "OrderByDescending";

        Expression methodCallExpression = Expression.Call(typeof(Queryable), methodName,
                                            new Type[] { source.ElementType, property.Type },
                                            source.Expression, Expression.Quote(lambda));

        return source.Provider.CreateQuery<T>(methodCallExpression);
    }
}

Source: http://weblogs.asp.net/davidfowler/archive/2008/12/11/dynamic-sorting-with-linq.aspx

Then you can rewrite this:

        if (SortDirection == "ASC")
        {
            this.grdCustomers.DataSource = dataContext.CustomerSet.OrderBy(i => i.DisplayName).Skip(skip).Take(PageSize);
        }
        else
        {
            this.grdCustomers.DataSource = dataContext.CustomerSet.OrderByDescending(i => i.DisplayName).Skip(skip).Take(PageSize);
        }

to

this.grdCustomers.DataSource = dataContext.CustomerSet.SortBy("DisplayName DESC").Skip(skip).Take(PageSize);
Sign up to request clarification or add additional context in comments.

1 Comment

bendewey, you're so money you don't even know how money you are...thanks a bunch for the push in the right direction.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.