How to pass an array of OrderBy expression to a method?
Asked Answered
I

1

8

I'm trying to enhance my repository so it is the one responsible for ordering. I've applied the answer from this question and as far as the repository is concerned, I'm pretty sure it done.

The problem I'm running into is that I'm not sure how to now pass an array to the methods in the repository. The compiler keeps yelling at me about delegates. In the linked question above, the author is essentially doing what I want so it must be possible.

Here's my repository code:

public virtual IList<TEntity> SelectOrderedList(
    Expression<Func<TEntity, bool>>[] Orderers,
    bool Ascending = true) {
    IOrderedQueryable<TEntity> TemporaryQueryable = null;

    foreach (Expression<Func<TEntity, bool>> Orderer in Orderers) {
        if (TemporaryQueryable == null) {
            TemporaryQueryable = (Ascending ? this.ObjectSet.OrderBy(Orderer) : this.ObjectSet.OrderByDescending(Orderer));
        } else {
            TemporaryQueryable = (Ascending ? TemporaryQueryable.ThenBy(Orderer) : TemporaryQueryable.ThenByDescending(Orderer));
        };
    };

    return TemporaryQueryable.ToList();
}

On a side note, I'm not 100% sure that I'm supposed to use Expression<Func<TEntity, bool>>. For some reason I have a feeling that it's supposed to be Expression<Func<TEntity, int>>, but I'm not too sure.

Anyway, I would really appreciate it if someone can show me how to actually call that. Bonus points and love if you can make it work like a params argument.

Inadmissible answered 18/2, 2011 at 23:13 Comment(3)
Re the bool/int/etc - this is the type of the member being compared. So for a string property, it is string.Genaro
Don't pass around Exp<Func<T, U>>[], pass around instead IOrderer<T>[] (take the second Type parameter out of the problem) #225981Saccular
@David, although I like what you suggest I'm not sure how to implement it and your answer in the linked question doesn't really give me a solution that makes sense to me. At the end of the day I want to do something like: SelectOrderedList(o1 => (o1.Something), o2 => (o2.SomethingElse)). So I want to pass in multiple expressions to the method so they can perform OrderBy/ThenBy...Inadmissible
A
8
public virtual IList<TEntity> SelectOrderedList(
    params Expression<Func<TEntity, IComparable>>[] Orderers) {
    IOrderedQueryable<TEntity> TemporaryQueryable = null;

    foreach (Expression<Func<TEntity, IComparable>> Orderer in Orderers) {
        if (TemporaryQueryable == null) {
            TemporaryQueryable = this.ObjectSet.OrderBy(Orderer);
        } else {
            TemporaryQueryable = TemporaryQueryable.ThenBy(Orderer);
        };
    };

    return TemporaryQueryable.ToList();
}

Then just use it as SelectOrderedList(o1 => (o1.Something), o2 => (o2.SomethingElse))...

Also, write another for Descending :)

If you want one, where each orderer can be ascending or descending, replace the signature with Tuple>,SortDirection> but you cannot use implicitly typed lambdas with implicitly typed tuples (and you cannot use them with implicit expressions either) so then, you'd have quite an ugly code when using it...

Acarpous answered 8/3, 2011 at 16:19 Comment(1)
+1, this definitely works in LINQ to Objects, but I ran into problems with LINQ to Entities and int properties. See this answer by @Slauma for a solution.Felicitasfelicitate

© 2022 - 2024 — McMap. All rights reserved.