Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Align errors
  • Loading branch information
michaelstaib committed Jun 28, 2024
commit 0c3fa86e921ffbb9bcddd53ec89b3ef22fb90d9d
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using static HotChocolate.ExecutableErrorHelper;

namespace HotChocolate;

Expand All @@ -27,7 +26,7 @@ internal sealed class DefaultAsyncEnumerableExecutable<T>(IAsyncEnumerable<T> so

if (await enumerator.MoveNextAsync())
{
throw new InvalidOperationException("Sequence contains more than one element.");
throw new GraphQLException(SequenceContainsMoreThanOneElement());
}

return result;
Expand All @@ -48,7 +47,7 @@ public override async ValueTask<List<T>> ToListAsync(CancellationToken cancellat
return result;
}

public async override IAsyncEnumerable<T> ToAsyncEnumerable(
public override async IAsyncEnumerable<T> ToAsyncEnumerable(
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
await foreach (var element in source.WithCancellation(cancellationToken).ConfigureAwait(false))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public IQueryableExecutable<T> WithSource(IQueryable<T> src)
{
if (source is EnumerableQuery)
{
return new ValueTask<T?>(source.SingleOrDefault());
return new ValueTask<T?>(SingleOrDefaultSync(source));
}

return SingleOrDefaultFromDataSourceAsync(cancellationToken);
Expand All @@ -79,12 +79,41 @@ public IQueryableExecutable<T> WithSource(IQueryable<T> src)
}

#if NET6_0_OR_GREATER
return await Task.Run(() => source.SingleOrDefault<T>(), cancellationToken).WaitAsync(cancellationToken);
return await Task.Run(() => SingleOrDefaultSync(source), cancellationToken).WaitAsync(cancellationToken);
#else
return await Task.Run(() => source.SingleOrDefault<T>(), cancellationToken);
return await Task.Run(() => SingleOrDefaultSync(source), cancellationToken);
#endif
}

private static T? SingleOrDefaultSync(IQueryable<T> query)
{
var enumerator = query.GetEnumerator();

try
{
if (enumerator.MoveNext())
{
var obj = enumerator.Current;

if(enumerator.MoveNext())
{
throw new GraphQLException(SequenceContainsMoreThanOneElement());
}

return obj;
}

return default;
}
finally
{
if(enumerator is IDisposable disposable)
{
disposable.Dispose();
}
}
}

public override ValueTask<List<T>> ToListAsync(CancellationToken cancellationToken = default)
{
if (source is EnumerableQuery)
Expand Down