传入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),它会正常工作。

我很好奇我是否正确地做到了这一点,或者在异步工作时是否有更好的选择来传递谓词。

传入function <type, bool>作为异步方法的参数

您的.Where( predicate )正在使用IEnumerable.Where扩展方法,而不是IQueryable.Where

这意味着谓词是在你的应用程序中运行的,而不是在数据库服务器上。

如果你想使用IQueryable.Where,你必须传递你的谓词作为Expression<Func<type, bool>> -一个表达式树-而不是作为一个委托。

因此,只需将方法签名更改为:

public async Task<IEnumerable<Type>>
  GetTypeSet(Expression<Func<Type, bool>> predicate)
{
  ...

我假设ToListAsyncIQueryable<T>而不是IEnumerable<T>的扩展方法。您应该将predicate参数的类型更改为Expression<Func<Type, bool>>

由于IQueryable<T>实现了IEnumerable<T>,所有IEnumerable<T>扩展方法,如Where(this IEnumerable<T>, Func<T, bool>)都是可用的,但通常不是你想要使用的。

由于predicateFunc<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();
}

欢呼