接受谓词和 orderby 的存储库方法

Dyl*_*rry 4 c# linq entity-framework

我已经使用 Entity Framework 设置了一个存储库,并具有以下接口方法:

Task<IList<Person>> SearchForPeople(Expression<Func<Person, bool>> predicate, Expression<Func<Person, object>> orderBy);
Run Code Online (Sandbox Code Playgroud)

这是相当基本的,我已将其实现为:

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();
}
Run Code Online (Sandbox Code Playgroud)

我目前这样称呼它:

var people = await repository.SearchForPeople(x => x.Born.Day == now.Day && x.Born.Month == now.Month, x => x.OrderingKey);
Run Code Online (Sandbox Code Playgroud)

它返回所有生日落在指定日期/月份的人,然后根据名为“orderingKey”的属性对他们进行排序,该属性本质上是他们的名字连接。

这工作正常,但如果我尝试将 orderby 更改为这样的:

var people = await repository.SearchForPeople(x => x.Born.Day == now.Day && x.Born.Month == now.Month, x => x.Born);
Run Code Online (Sandbox Code Playgroud)

我收到一条错误消息,说我无法将 System.DateTime 转换为 System.Object。我明白为什么会发生这种情况,因为我已经明确指出 orderby 属性应该是“对象”类型,但我看不出如何重写它,以便我的 orderby 接受任何类型的属性给 orderby,而无需使用通用 T,我真的不想这样做,因为我不想要一个通用存储库只是一个通用过滤器!

有没有另一种方法可以使两种类型的 orderby 都起作用?

Cod*_*gue 6

您可以使该方法通用:

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();
}
Run Code Online (Sandbox Code Playgroud)

然后使用类型推断,以下应该有效:

var people = await repository.SearchForPeople(x => x.Born.Day == now.Day && x.Born.Month == now.Month, x => x.Born);
Run Code Online (Sandbox Code Playgroud)