EF6 - 将await关键字与Where()子句一起使用

use*_*648 6 asynchronous where async-await entity-framework-6 asp.net-mvc-5

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

这是我的代码有效:

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;
}
Run Code Online (Sandbox Code Playgroud)

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

Account account = await db.accounts.Where(a => a.userName.Equals(userName)).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

可以在await关键字使用时,可使用.Where()条款?

提前致谢.

hai*_*770 13

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

Account account = await db.accounts.FirstOrDefaultAsync(a => a.userName.Equals(userName));
Run Code Online (Sandbox Code Playgroud)

请参阅MSDN


t0y*_*k4t 5

return关键字只能用于返回“ Task ...”的方法,也.Where不能.FirstOrDefault(返回链中的最后一个方法,因此它将是await关键字将应用于的方法)returnTask<IEnumerable<Account>>

从理论上讲,您可以编写自己的扩展方法,将扩展方法.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));
    }
}
Run Code Online (Sandbox Code Playgroud)

虽然那会是一种过大的恕我直言。

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

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;
    });
}
Run Code Online (Sandbox Code Playgroud)