Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting Gridview with Entity Framework.

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

like image 539
jim Avatar asked Feb 03 '23 01:02

jim


1 Answers

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);
like image 101
bendewey Avatar answered Feb 05 '23 18:02

bendewey