Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repository method accepting predicate and orderby

I’ve set up a repository with Entity Framework and have the following interface method:

Task<IList<Person>> SearchForPeople(Expression<Func<Person, bool>> predicate, Expression<Func<Person, object>> orderBy);

It’s fairly basic, and I’ve implemented it as:

public async Task<IList<Person>> SearchForPeople(Expression<Func<Person, bool>> predicate, Expression<Func<Person, object>> orderBy)
{
    return await this.context.People.Where(predicate).OrderBy(orderBy).ToListAsync();
}

I’m currently calling it like this:

var people = await repository.SearchForPeople(x => x.Born.Day == now.Day && x.Born.Month == now.Month, x => x.OrderingKey);

Which returns all the people whose birthdays fall on the specified day/month, and then orders them according to a property called "orderingKey" which is essentially their name concatenated.

This works fine, but if I try to change the orderby to something like this:

var people = await repository.SearchForPeople(x => x.Born.Day == now.Day && x.Born.Month == now.Month, x => x.Born);

I get an error saying that I cannot cast System.DateTime to System.Object. I understand why this is happening as I’ve clearly stated that the orderby property should be of type “object”, but I cannot see how to rewrite this so that my orderby accepts any type of property to orderby without rewriting the whole thing using the generic T, which I don’t really want to do as I don’t want a generic repository just a generic filter!

Is there another way of making both types of orderby work?

like image 205
Dylan Parry Avatar asked Mar 19 '23 13:03

Dylan Parry


1 Answers

You can make just that method generic:

public async Task<IList<Person>> SearchForPeople<T>(Expression<Func<Person, bool>> predicate, Expression<Func<Person, T>> orderBy)
{
    return await this.context.People.Where(predicate).OrderBy(orderBy).ToListAsync();
}

Then using type inference, the following should work:

var people = await repository.SearchForPeople(x => x.Born.Day == now.Day && x.Born.Month == now.Month, x => x.Born);
like image 113
CodingIntrigue Avatar answered Mar 24 '23 03:03

CodingIntrigue