1

I have this generic method that I'm trying to make, and in order to achieve that I want to pass an IOrderedQueryable as a parameter.

public async Task<IEnumerable<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> filter, IOrderedQueryable orderBy){
    IQueryable<TEntity> query = dbSet;
    query = query.Where(filter);
    query = query.OrderBy(orderBy); //This is what I want to do
    return await query.ToListAsync();
}

I want to pass an IOrderedQueryable from outside in order to be able to make the function depending on a string and be able to look at the properties of my object (without reflection), for one and each of my objects.

public static Func<IQueryable<MyObject>, string, IOrderedQueryable<Entity>> OrderBy = (query, orderBy) =>
    {
        return orderBy switch
        {
            "Id" => query.OrderBy(x => x.Id),
            "Prop1" => query.OrderBy(x => x.Prop1),
            "Prop2" => query.OrderBy(x => Prop2),
            _ => query.OrderBy(x => x.Id)
        };
    };

I don't know if I change the order if it would have any impact.

query = orderBy;
query = query.Where(filter);

Or I don't know if I can do a Concat, or if that would make me lose my where clause

query = query.Concat(orderBy);
  • 1
    What you want is `Expression>`. `IOrderedQueryable` is the result of calling `OrderBy`. – juharr Mar 30 '22 at 00:01
  • @juharr and what would it be TKey? – Ricardo Sanchez Santos Mar 30 '22 at 00:47
  • Unpacking an `IOrderedQueryable` so you can apply the order to another query... is going to be a mess. I also dislike how the `Queryable.OrderBy` extension methods depend so heavily on generics and are so difficult to use in a dynamic way. If you look at how those methods work (https://github.com/dotnet/runtime/blob/238b3c61c4ea878174c640a146c0777b08cebcec/src/libraries/System.Linq.Queryable/src/System/Linq/Queryable.cs#L153) you can create something equivalent (maybe like https://stackoverflow.com/a/36303246/4139809, or with a prebuilt dictionary of lambda expressions) – Jeremy Lakeman Mar 30 '22 at 01:02
  • `TKey` would be a generic type defined on the method that would allows you to pass a lambda that picked whatever you want to order on. But why not pass in the `string` value, then put the `switch` statement in your code instead? – juharr Mar 30 '22 at 02:04
  • If you really want it to be generic, you would need a way to allow ascending and descending orders and you would need a way to allow OrderBy(...).ThenBy(...) chains. If you can trust your callers not to abuse the parameter, you could do something like `Func, IQueryable> orderFunc` and then use it in your function as `query = orderFunc(query);`. If you want a greater level of control you could follow juharrs suggestion or pass a list of (PropertyName, Direction) in order to construct the sorting... the more control you take, the method becomes less "generic" – grek40 Mar 30 '22 at 06:20

0 Answers0