1

I have just started this week to learn ASP.Net core 2.0 with EF Core and MVC using C#. So i am a complete Noob.

Is they a way to create a dynamic Switch (SortOrder) using a dynamic parameters pulled from a Model/restful API? this is so my Switch statements don't end up 30+ cases deep.

i am looking for something on the lines of this Sudo:

switch (sortOrder)
{
    default:
        Tickets = Tickets.OrderBy(s => s.ID);
        break;
    foreach (string Tick in Tickets)
        {
        case Tick :
           Tickets = Tickets.OrderBy(T => Tick);
           break;
 }

for reference part of my TicketController

public async Task<IActionResult> Index(string sortOrder, string searchString)
{
    //sorting
    ViewData["NameSortParm"] = String.IsNullOrEmpty(sortOrder) ? "ID" : "";
    ViewData["DateSortParm"] = sortOrder == "ID" ? "Environment" : "Date";
    ViewData["CurrentFilter"] = searchString;

    var Tickets = from s in _context.MyTickets
                   select s;
    // search
    if (!String.IsNullOrEmpty(searchString))
    {
        Tickets = Tickets.Where(T => T.ID.ToString().Contains(searchString)
                               || T.Environment.Contains(searchString)
                               || T.YourRef.Contains(searchString)
                               || T.Priority.Contains(searchString)
                               || T.Type.Contains(searchString)
                               || T.ProductName.Contains(searchString)
                               || T.Environment.Contains(searchString)
                               || T.Version.Contains(searchString)
                               || T.Description.Contains(searchString)
                               || T.Status.Contains(searchString)
                               || T.Contact.Contains(searchString));
    }
    ////sorting
    //switch (sortOrder)
    //{
    //    case "ID":
    //        Tickets = Tickets.OrderByDescending(s => s.ID);
    //        break;
    //    case "Date":
    //        Tickets = Tickets.OrderBy(s => s.CreatedDate);
    //        break;
    //    case "Environment":
    //        Tickets = Tickets.OrderBy(s => s.Environment);
    //        break;
    //    default:
    //        Tickets = Tickets.OrderBy(s => s.ID);
    //        break;
    //}

    switch (sortOrder)
    {
        default:
            Tickets = Tickets.OrderBy(s => s.ID);
            break;
        foreach (string Tick in Tickets)
            {
                case Col :
            Tickets = Tickets.OrderBy(T => Col)
       }


    }


    // return results
    return View(await Tickets.AsNoTracking().ToListAsync());
}
Rand Random
  • 7,300
  • 10
  • 40
  • 88
Max
  • 17
  • 8
  • Have a look into OData. You can pass through filtering and ordering (among other options) when creating a OData compliant REST-API. See http://www.odata.org/documentation/odata-version-2-0/uri-conventions/ Section 4.2 This is supported by WCF as well as ASP.NET Web API. – Fildor Mar 13 '18 at 11:42
  • Consider using [Dynamic LINQ](https://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library) –  Mar 13 '18 at 11:49
  • I've flagged this as a duplicate question, but take a look at [this answer](https://stackoverflow.com/a/7265354/1663001) on how to order using expressions which is relevant with Entity Framework. – DavidG Mar 13 '18 at 12:02

1 Answers1

0

This will use reflection to sort by a property matching the sortOrder string:

    Tickets = Tickets.OrderBy(s => s.GetProperty(sortOrder).GetValue(s));

The sortOrder will need to exactly match the name of the property you want to sort by ("CreatedDate", not "Date").

Alternatively you can change your method signature to accept a function instead of a string for the sortOrder:

public async Task<IActionResult> Index(Func<Ticket, object> sortOrder, string searchString)
{
    ...

    Tickets = Tickets.OrderBy(s => sortOrder(s));

    ...
}

And you can call this passing (s => s.Environment, ...

Steve Harris
  • 5,014
  • 1
  • 10
  • 25
  • This will cause the ordering to happen in the client app rather than the database though... – DavidG Mar 13 '18 at 11:54
  • Or more likely this will just throw errors – DavidG Mar 13 '18 at 11:55
  • Both true. Need exception handling! – Steve Harris Mar 13 '18 at 11:55
  • No, I mean if `Tickets` is an `IQueryable`, using something like EF Core, it will get passed along to the provider which will explode when trying to figure out what to do. So, what you are proposing is *not* possible unless you force the ordering to happen on the client. – DavidG Mar 13 '18 at 11:57
  • The only way to do this with EF would be to create an `Expression` manually, and that's pretty complex though I'm sure there will be a dupe on the site somewhere. – DavidG Mar 13 '18 at 12:00
  • thanks for the answer but, this is currently a little over my head to understand and implement as of yet, i think i need to do more research.... – Max Mar 14 '18 at 10:08