I am coding a MVC 5 internet application with entity framework 6 and have a question in regards to using the await
keyword when using the .Where()
clause.
Here is my code that works:
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;
}
I am wanting to use the await keyword when retrieving the Account object
as follows:
Account account = await db.accounts.Where(a => a.userName.Equals(userName)).FirstOrDefault();
Can the await
keyword be used when using the .Where()
clause?
Thanks in advance.
The await keyword can only be used on methods that return "Task...", neither .Where
nor .FirstOrDefault
(Which is the last method in the chain, and thus would be the one the await keyword would apply to) return Task<IEnumerable<Account>>
In theory you could write you own extension method which simply wraps around the .Where
and .FirstOrDefault
methods.
Also, this question isn't exactly EF specific, but rather a 'pure' C# question.
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));
}
}
Although that would be kind of overkill imho.
You could just wrap your entire method in a Task, so your final code would be something like:
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;
});
}
There is no WhereAsync()
method provided by EF (obviously because it can't potentially block, since LINQ uses deferred-execution), but since you're performing a FirstOrDefault()
you could simply use the FirstOrDefaultAsync()
method:
Account account = await db.accounts.FirstOrDefaultAsync(a => a.userName.Equals(userName));
See MSDN