Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support more fields in GridView SortExpression #1730

Open
holajan opened this issue Nov 3, 2023 · 1 comment
Open

Support more fields in GridView SortExpression #1730

holajan opened this issue Nov 3, 2023 · 1 comment

Comments

@holajan
Copy link
Contributor

holajan commented Nov 3, 2023

Change GridViewDataSet ApplySortingToQueryable method to support more fields in SortExpression separated by a comma.

Used for example like this:

<dot:GridViewTextColumn ValueBinding="{value: CeleJmeno}" AllowSorting="true" SortExpression="Prijmeni,Jmeno" HeaderText="Jméno zaměstnance" />

GridViewDataSet ApplySortingToQueryable method will be:

public virtual IQueryable<T> ApplySortingToQueryable(IQueryable<T> queryable)
{
    if (this.SortingOptions?.SortExpression == null)
    {
        return queryable;
    }

    var parameterExpression = Expression.Parameter(typeof(T), "p");
    Expression? sortExpression = null;

    foreach (string propertySortExpression in (this.SortingOptions.SortExpression ?? "").Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
    {
        Expression sortByExpression = parameterExpression;

        foreach (string prop in propertySortExpression.Trim().Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries))
        {
            var property = sortByExpression.Type.GetTypeInfo().GetProperty(prop);
            if (property == null)
            {
                throw new Exception($"Could not sort by property '{prop}', since it does not exists.");
            }
            if (property.GetCustomAttribute<BindAttribute>() is BindAttribute bind && bind.Direction == Direction.None)
            {
                throw new Exception($"Cannot sort by an property '{prop}' that has [Bind(Direction.None)].");
            }
            if (property.GetCustomAttribute<ProtectAttribute>() is ProtectAttribute protect && protect.Settings == ProtectMode.EncryptData)
            {
                throw new Exception($"Cannot sort by an property '{prop}' that is encrypted.");
            }

            sortByExpression = Expression.Property(sortByExpression, property);
        }

        if (sortByExpression == parameterExpression)
        {
            continue;
        }

        var lambdaExpression = Expression.Lambda(sortByExpression, parameterExpression);
        var methodCallExpression = Expression.Call(typeof(Queryable), GetSortingMethodName(sortExpression == null),
            new[] { parameterExpression.Type, sortByExpression.Type },
            sortExpression ?? queryable.Expression,
            Expression.Quote(lambdaExpression));

        sortExpression = methodCallExpression;
    }

    if (sortExpression == null) //No sorting
    {
        return queryable;
    }

    return queryable.Provider.CreateQuery<T>(sortExpression);
}

private string GetSortingMethodName(bool isFirst)
{
    return isFirst ?
        this.SortingOptions.SortDescending ? "OrderByDescending" : "OrderBy" :
        this.SortingOptions.SortDescending ? "ThenByDescending" : "ThenBy";
}
@exyi
Copy link
Member

exyi commented Nov 19, 2023

This is planned for version 5. We already have a multi-criteria sorting implemented (https://github.com/riganti/dotvvm/blob/d57ecbb1613b37c2b2363264386d55b500412c6f/src/Framework/Core/Controls/Options/MultiCriteriaSortingOptions.cs), although it will have to be enabled specifically in each dataset. We didn't want to add more complex syntax to the SortExpression, since it then becomes nearly impossible to process client-side (flip direction, highlight sorted columns, ...)

We will let you know when we release a preview with this feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants