1

I need pass parameter to linq query. My query is as follows:

var appointments = (from a in inMemContext.Appointments
                    join u in inMemContext.Users on a.UserId equals u.UserId into AppointmentAssignments
                    from aa in AppointmentAssignments.DefaultIfEmpty()
                    join l in inMemContext.Languages on a.PreferredLanguage equals l.LanguageKey
                    where a.BranchId == branchId
                    && a.AppointmentDate.Date == TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById(b.TimeZoneId)).Date 
                    orderby a.AppointmentTime
                    select new AppointmentEntryDetailsDto
                    {
                        Id = a.AppointmentId.ToString(),
                        StartTime = (a.AppointmentTime).ToString("hh:mm tt", CultureInfo.InvariantCulture),
                        AppointmentType = a.AppointmentType.AppointmentTypeName,
                    });

In above query I'm taking data ordered by AppointmentTime. Now I need set dynamic sorted value as ascending or descending.

For this line:

orderby a.AppointmentTime [OrderParameter]

ascending or descending. How can I do this?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
thomsan
  • 433
  • 5
  • 19

2 Answers2

1

This is achievable by creating an extension method which can dynamically change whether it's ascending or descending:

public static class LinqExtensions
{
    public static IEnumerable<TModel> OrderByDynamic<TModel, TKey>(this IEnumerable<TModel> source, Func<TModel, TKey> selector, bool ascending = true)
    {
        if (ascending) return source.OrderBy(selector);
        return source.OrderByDescending(selector);
    }
}

Usage:

var appointmentList = new List<Appointment>
{
    new Appointment { UserId = "1", PreferredLanguage = "English", BranchId = "1", AppointmentDateTime = new DateTime(2000, 1, 1, 0, 0, 0) },
    new Appointment { UserId = "2", PreferredLanguage = "Japanese", BranchId = "1", AppointmentDateTime = new DateTime(2000, 2, 1, 0, 0, 0) },
    new Appointment { UserId = "3", PreferredLanguage = "Spanish", BranchId = "2", AppointmentDateTime = new DateTime(2000, 3, 1, 0, 0, 0) },
};

// Order By Descending
var appointments = appointmentList.OrderByDynamic(selector: x => x.AppointmentDateTime, ascending: false);

This is not directly compatible with a Linq Query, but can be used on the results of any IEnumerable. I'll leave that up to you on how to use this for your specific case.

Hayden
  • 2,902
  • 2
  • 15
  • 29
  • How can I apply this into mycode, here you are using `appointmentList` . I'm bit confused to apply this to my code – thomsan Jul 31 '20 at 08:09
  • `appointmentList` is just an example since I don't have access to your Data Context. What's important is that you can apply the code if you refactor the code to either use the extension methods instead of Linq Query or if you apply the method after the fact. That I will leave up to you. – Hayden Jul 31 '20 at 08:29
0

There is no such built in way.

You can create a custom extension method (thereby not using language integrated queries), or branch the entire statement, or order by the negative time (convert the time based on the parameter before ordering, subtract from 24:00:00 or similar).

Lemon Sky
  • 677
  • 4
  • 10