我已经使用Entity Framework建立了一个存储库,并具有以下接口方法:
Task<IList<Person>> SearchForPeople(Expression<Func<Person, bool>> predicate, Expression<Func<Person, object>> orderBy);
这是相当基本的,我已将其实现为:
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();
}
我现在这样称呼它:
var people = await repository.SearchForPeople(x => x.Born.Day == now.Day && x.Born.Month == now.Month, x => x.OrderingKey);
返回生日落在指定日/月的所有人,然后根据名为“orderingKey”的属性对其进行排序,该属性基本上是他们的名称连接。
这样可以正常工作,但如果我尝试将orderby更改为类似的内容:
var people = await repository.SearchForPeople(x => x.Born.Day == now.Day && x.Born.Month == now.Month, x => x.Born);
我收到错误消息,说我无法将System.DateTime强制转换为System.Object。我理解为什么会发生这种情况,因为我已经清楚地说明了orderby属性应该是“object”类型,但是我看不到如何重写这个以便我的orderby接受任何类型的属性来命令而不用使用它重写整个东西通用T,我真的不想这样做,因为我不希望通用存储库只是一个通用的过滤器!
还有另一种方法可以使这两种类型的订单工作吗?
答案 0 :(得分:4)
您可以将该方法设为通用:
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();
}
然后使用类型推断,以下内容应该有效:
var people = await repository.SearchForPeople(x => x.Born.Day == now.Day && x.Born.Month == now.Month, x => x.Born);
答案 1 :(得分:1)
试试这个:
public async Task<IList<Person>> SearchForPeople<TOrderKey>(Expression<Func<Person, bool>> predicate, Expression<Func<Person, TOrderKey>> orderBy)
{
return await this.context.People.Where(predicate).OrderBy(orderBy).ToListAsync();
}
您可以将其定义为通用参数,而不是传入“对象”。