3

我正在修改现有项目以利用 EF6 (alpha3) 异步扩展方法。我有一种方法采用 func 参数,该参数被传递到 linq to entity 查询中。这是工作代码的示例,预异步:

public IEnumerable<type> GetTypeSet(Func<Type, bool> predicate)
    {
        return dbSet.Where(d => d.isPublic == true).Where(predicate).tolist();
    }

应用异步后:

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)它可以正常工作。

我很好奇我是否正确地解决了这个问题,或者在异步工作时是否有更好的选择来传递谓词。

4

3 回答 3

7

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

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

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

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

public async Task<IEnumerable<Type>>
  GetTypeSet(Expression<Func<Type, bool>> predicate)
{
  ...
于 2013-03-25T23:15:53.660 回答
5

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

由于IQueryable<T>实现IEnumerable<T>了所有的IEnumerable<T>扩展方法,likeWhere(this IEnumerable<T>, Func<T, bool>)都是可用的,但通常不是您打算使用的。

因为predicate是一个Func<Type, bool>类型

dbSet.Where(d => d.isPublic == true)

IEnumerable<Type>你想要的时候IQueryable<Type>。更改 to 的类型predicateExpression<Func<Type, bool>>导致使用Queryable.Where扩展方法,该方法根据需要返回一个IQueryable<Item>

于 2013-03-25T23:15:46.177 回答
3

您必须使函数采用表达式,否则 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();
}

干杯

于 2013-03-25T23:17:30.143 回答