1

I'm new to dotnet core. I'm creating a web api and have implemented the sorting using this link. I have a SortFilter class where I receive the column and order:

    public class SortFilter
{
    public string sortBy { get; set; } //Column name
    public string order { get; set; } //asc or desc
}

Then in the services, I use the provided information to sort the response accordingly:

//Sort
        switch (sortFilter.sortBy)
        {
            case "name_ar":
                {
                    switch (sortFilter.order)
                    {
                        case "asc":
                            {
                                pagedData = pagedData.OrderBy(s => s.name_ar);
                                break;
                            }
                        case "desc":
                            {
                                pagedData = pagedData.OrderByDescending(s => s.name_ar);
                                break;
                            }
                        default:
                            {
                                pagedData = pagedData.OrderBy(s => s.name_ar);
                                break;
                            }
                    }
                    break;
                }

            case "name_en":
                {
                    switch (sortFilter.order)
                    {
                        case "asc":
                            {
                                pagedData = pagedData.OrderBy(s => s.name_en);
                                break;
                            }
                        case "desc":
                            {
                                pagedData = pagedData.OrderByDescending(s => s.name_en);
                                break;
                            }
                        default:
                            {
                                pagedData = pagedData.OrderBy(s => s.name_en);
                                break;
                            }
                    }
                    break;
                }

            case "description_ar":
                {
                    switch (sortFilter.order)
                    {
                        case "asc":
                            {
                                pagedData = pagedData.OrderBy(s => s.description_ar);
                                break;
                            }
                        case "desc":
                            {
                                pagedData = pagedData.OrderByDescending(s => s.description_ar);
                                break;
                            }
                        default:
                            {
                                pagedData = pagedData.OrderBy(s => s.description_ar);
                                break;
                            }
                    }
                    break;
                }

            case "description_en":
                {
                    switch (sortFilter.order)
                    {
                        case "asc":
                            {
                                pagedData = pagedData.OrderBy(s => s.description_en);
                                break;
                            }
                        case "desc":
                            {
                                pagedData = pagedData.OrderByDescending(s => s.description_en);
                                break;
                            }
                        default:
                            {
                                pagedData = pagedData.OrderBy(s => s.description_en);
                                break;
                            }
                    }
                    break;
                }

            case "orderNumber":
                {
                    switch (sortFilter.order)
                    {
                        case "asc":
                            {
                                pagedData = pagedData.OrderBy(s => s.orderNumber);
                                break;
                            }
                        case "desc":
                            {
                                pagedData = pagedData.OrderByDescending(s => s.orderNumber);
                                break;
                            }
                        default:
                            {
                                pagedData = pagedData.OrderBy(s => s.orderNumber);
                                break;
                            }
                    }
                    break;
                }


            case "id":
                {
                    switch (sortFilter.order)
                    {
                        case "asc":
                            {
                                pagedData = pagedData.OrderBy(s => s.id);
                                break;
                            }
                        case "desc":
                            {
                                pagedData = pagedData.OrderByDescending(s => s.id);
                                break;
                            }
                        default:
                            {
                                pagedData = pagedData.OrderBy(s => s.id);
                                break;
                            }
                    }
                    break;

                }

            default:
                pagedData = pagedData.OrderBy(s => s.id);
                break;
        }

What I'm not liking about this approach is this big chunk of code repeating in all the services, specific for each entities' columns.

I tried to create a template Sort Class where I can do something like:

pagedData = pagedData.OrderBy(s => s[sortFilter.sortBy]) //using variable column name

But, this is not allowed. Can anyone suggest me an alternative?

0RR
  • 1,538
  • 10
  • 21
Tayyab Mir
  • 23
  • 5

2 Answers2

2

If the value of sortBy is going to be the same as the field name you could use reflection.

Here is another SO post on doing that: How do I specify the Linq OrderBy argument dynamically?

The code in the previous link:

var param = "Address";    
var propertyInfo = typeof(Student).GetProperty(param);    
var orderByAddress = items.OrderBy(x => propertyInfo.GetValue(x, null));

You will have to change Student and the param field to match your types.

Quintonn
  • 770
  • 8
  • 29
0

Yes, there's a way, but the switch case will be more performant, it's more a decision of whether you want cleaner code or faster code, you can use reflexion to get the properties of your models. Here's a tutorial explaining how to do so, the tutorial isn't super clean, but you should get the idea on how to do it.

https://khalidabuhakmeh.com/sort-data-with-aspnet-core-and-query-strings

Make sure you implement unit testing if you are using reflexion to avoid future issues! ;)

MathieuAuclair
  • 1,229
  • 11
  • 41
  • 1
    Thankyou for replying. The article definitely gave me the right direction. Though I'd prefer to get the single property like Quintonn mentioned instead of getting all the properties and then comparing them. Thanks for the heads up on its performance though! Will definitely monitor the difference with and without reflexion. – Tayyab Mir Jan 05 '21 at 08:55