传入function 作为异步方法的参数
本文关键字:异步方法 参数 bool function type 传入 | 更新日期: 2023-09-27 18:05:55
我正在修改一个现有的项目,以利用EF6 (alpha3)异步扩展方法。我有一个方法,它接受一个函数参数,它被传递到linq到实体查询中。下面是一个工作代码的例子,pre-async:
public IEnumerable<type> GetTypeSet(Func<Type, bool> predicate)
{
return dbSet.Where(d => d.isPublic == true).Where(predicate).tolist();
}
应用async:
public async Task<IEnumerable<Type>> GetTypeSet(Func<Type, bool> predicate)
{
return await(dbSet.Where(d => d.isPublic == true)
.Where(predicate)).ToListAsync();
}
此时,我得到一个错误,指出IEnumerable没有ToListAsync的定义。如果我移除.Where(predicate)
,它会正常工作。
我很好奇我是否正确地做到了这一点,或者在异步工作时是否有更好的选择来传递谓词。
您的.Where( predicate )
正在使用IEnumerable.Where
扩展方法,而不是IQueryable.Where
。
这意味着谓词是在你的应用程序中运行的,而不是在数据库服务器上。
如果你想使用IQueryable.Where
,你必须传递你的谓词作为Expression<Func<type, bool>>
-一个表达式树-而不是作为一个委托。
因此,只需将方法签名更改为:
public async Task<IEnumerable<Type>>
GetTypeSet(Expression<Func<Type, bool>> predicate)
{
...
我假设ToListAsync
是IQueryable<T>
而不是IEnumerable<T>
的扩展方法。您应该将predicate
参数的类型更改为Expression<Func<Type, bool>>
。
由于IQueryable<T>
实现了IEnumerable<T>
,所有IEnumerable<T>
扩展方法,如Where(this IEnumerable<T>, Func<T, bool>)
都是可用的,但通常不是你想要使用的。
由于predicate
是Func<Type, bool>
,所以类型
dbSet.Where(d => d.isPublic == true)
当您希望为IQueryable<Type>
时,它是IEnumerable<Type>
。将predicate
的类型更改为Expression<Func<Type, bool>>
将导致使用Queryable.Where
扩展方法,该方法返回所需的IQueryable<Item>
。
你必须让函数接受一个表达式,否则Where扩展将退回到IEnumerable,而不是IQueryable。而ToListAsync只是IQueryable的一个扩展方法。
public async Task<IEnumerable<Type>> GetTypeSet(Expression<Func<Type, bool>> predicate)
{
return await(dbSet.Where(d => d.isPublic == true)
.Where(predicate)).ToListAsync();
}
欢呼