Presi
Presi

Reputation: 827

Multiple Linq functions as parameter

I have a method which searchs Items in the Database. Because I use it multiple times I made it generic:

public async Task Search(Expression<Func<T, bool>> criteria, Func<T, object> order)
{
    return Task.Run(async () => Searchlist.AddRange((await Service.SearchAsync(criteria, false)).AsEnumerable().OrderBy(order)));
}

Because it is generic, I implement the parameter order, that they are ordered correctly. I call the method like this:

await Search(GetCriteria(), p => p.Description);

But I have some objects which are ordered by multiple (between 2 and 4) properties. So they are ordered like this:

SearchAsync(criteria, false)).AsEnumerable().OrderBy(x => x.Date).ThenBy(y => y.Nr).ThenBy(z => z.Type))

Can I create a parameter where I can put the Methods to call. Like .OrderBy(x => x.Date).ThenBy(y => y.Nr).ThenBy(z => z.Type) or only .OrderBy(x => x.Date).

Thanks

Upvotes: 1

Views: 180

Answers (1)

Jota.Toledo
Jota.Toledo

Reputation: 28434

If you are able to break the current interface of your function, go with:

public async Task Search(Expression<Func<T, bool>> criteria, Func<T, object>[] order)
{
    var elems = await Service.SearchAsync(criteria, false);
    var sorted = elems.AsEnumerable().OrderBy(order.First());
    foreach(var subOrder in order.Skip(1)){
      sorted = sorted.ThenBy(subOrder);
    }
    Searchlist.AddRange(sorted)
}

await Search(GetCriteria(), new []{p => p.Date, p => p.Description});

If you dont want to break the current interface, go with:

public async Task Search(
   Expression<Func<T, bool>> criteria, 
   Func<T, object> mainOrder, 
   params Func<T, object>[] subOrders)
{
    var elems = await Service.SearchAsync(criteria, false);
    var sorted = elems.AsEnumerable().OrderBy(mainOrder);
    foreach(var subOrder in subOrders){
      sorted = sorted.ThenBy(subOrder);
    }
    Searchlist.AddRange(sorted)
}

await Search(GetCriteria(), p => p.Date, p => p.Description);

Upvotes: 3

Related Questions