EF6 - 在 Where() 子句中使用 await 关键字

Posted

技术标签:

【中文标题】EF6 - 在 Where() 子句中使用 await 关键字【英文标题】:EF6 - Using the await keyword with the Where() clause 【发布时间】:2015-02-08 15:05:27 【问题描述】:

我正在使用实体框架 6 编写 MVC 5 互联网应用程序,并且在使用 .Where() 子句时对使用 await 关键字有疑问。

这是我的有效代码:

public async Task<Account> GetAccount(string userName)

    if (Session[userName] == null)
    
        Account account = db.accounts.Where(a => a.userName.Equals(userName)).FirstOrDefault();
        if (account == null)
        
            //log out
            return null;
        
        Session[userName] = account;
    
    return Session[userName] as Account;

我想在检索 Account object 时使用 await 关键字,如下所示:

Account account = await db.accounts.Where(a => a.userName.Equals(userName)).FirstOrDefault();

在使用.Where() 子句时可以使用await 关键字吗?

提前致谢。

【问题讨论】:

【参考方案1】:

EF 没有提供 WhereAsync() 方法(显然因为它不可能阻塞,因为 LINQ 使用延迟执行),但是因为您正在执行 FirstOrDefault() 你可以简单地使用FirstOrDefaultAsync() 方法:

Account account = await db.accounts.FirstOrDefaultAsync(a => a.userName.Equals(userName));

见MSDN

【讨论】:

谢谢!这对我有用。【参考方案2】:

await 关键字只能用于返回“Task...”的方法,.Where.FirstOrDefault 都不是(这是链中的最后一个方法,因此将是 await 关键字适用的方法to) 返回Task&lt;IEnumerable&lt;Account&gt;&gt;

理论上,您可以编写自己的扩展方法,该方法简单地包裹.Where.FirstOrDefault 方法。

此外,这个问题并不完全是 EF 特定的,而是一个“纯”C# 问题。

public static class ExtensionMethods

    public static async Task<IEnumerable<T>> WhereAsync<T>(this IEnumerable<T> source, Func<T, bool> selector)
    
        return await Task.Run(() => source.Where(selector));
    

虽然这有点矫枉过正。

您可以将整个方法包装在一个任务中,因此您的最终代码将类似于:

public async Task<Account> GetAccount(string userName)

    return await Task.Run(() =>
    
        if (Session[userName] == null)
        
            Account account = db.accounts.Where(a => a.userName.Equals(userName)).FirstOrDefault();
            if (account == null)
            
                //log out
                return null;
            
            Session[userName] = account;
        
        return Session[userName] as Account;
    );

【讨论】:

以上是关于EF6 - 在 Where() 子句中使用 await 关键字的主要内容,如果未能解决你的问题,请参考以下文章

实体框架:Count() 在大型 DbSet 和复杂的 WHERE 子句上非常慢

EF 6.x,LINQ-to-SQL和原始SQL子句

如何在 EXECUTE IMMEDIATE 中使用动态 where 子句

不使用`where`子句,但得到错误:“未知列 在where子句中“

在 where 子句中使用 CASE

如何在 WHERE 子句中使用条件不同的列?