IQueryable - TryFirst (async) -- Replacement for .FirstOrDefaultAsync() -- Is this helpful for a PR?
See original GitHub issueHello all,
I am new to this library, I am working with EFCore. In my scenerio I am working with IQueryable<T>.
I wanted a method like .FirstOrDefaultAsync(), because when I used .FirstOrDefaultAsync(), my return object was a pain, and looked like: Result<Maybe<TEntity?>, Error> , the nullable ? was giving me warnings in code.
I saw the methods TryFirst and TryLast - success I thought! But then I realized that these are not async, and do not use IQueryable
I created these methods for async and IQueryable:
public static async Task<Maybe<T>> TryFirstAsync<T>(
this IQueryable<T> source,
CancellationToken cancellationToken = default)
{
var firstOrNull = await source.FirstOrDefaultAsync(cancellationToken);
if (firstOrNull == null)
{
return Maybe<T>.None;
}
return Maybe<T>.From(firstOrNull);
}
public static async Task<Maybe<T>> TryFirstAsync<T>(
this IQueryable<T> source,
Func<T, bool> predicate,
CancellationToken cancellationToken = default)
{
var firstOrEmpty = source.AsEnumerable()
.Where(predicate)
.Take(1)
.AsQueryable();
var firstOrNull = await firstOrEmpty.FirstOrDefaultAsync(cancellationToken);
if (firstOrNull == null)
{
return Maybe<T>.None;
}
return Maybe<T>.From(firstOrNull);
}
Note
Note: I realize that we do not use the Async suffix, however, using the suffix made things must easier, because without the suffix, the method would default to the IEnumerable<T> version, when I wanted to use the IQueryable<T> version.
Question
Is this helpful at all?
What should I do to replace IQueryable<T>.FirstOrDefaultAsync() in the future if this code is not helpful?
Issue Analytics
- State:
- Created 10 months ago
- Reactions:1
- Comments:8 (3 by maintainers)

Top Related StackOverflow Question
We can add these 2 extension methods if we don’t have them yet.
Asyncpostfix is fine to make it consistent with EF Core.Regarding your second overload: please use @maxime-poulain 's version. This code:
doesn’t work because converting the
sourceto IEnumerable withAsEnumerable()will prompt EF Core to load the whole set of items and then do the filtration in-memory, which defeats the purpose of usingIQueriable.Lucian Wischik, who worked on the compiler for async/await pattern is clear:
So everyting you say regarding having API with
Taskreturning method when the input is anIQueryableis right. https://youtu.be/OpOaiz4mNP0?t=466 (The guy himself explains it there if you are interessted).BTW
FirstOrDefaultAsynchas an overload that takes anExpression. You can have