ToAsyncEnumerable (). Single () vs SingleAsync ()

I create and execute my queries in a way that is independent of EF-Core, so I rely on IQueryable<T>to get the required level of abstraction. I replace expected calls SingleAsync()with expected calls ToAsyncEnumerable().Single(). I also replace calls with ToListAsync()calls ToAsyncEnumerable().ToList(). But I just came up with the method ToAsyncEnumerable(), so I'm not sure if I use it correctly or not.

To clarify which extension methods I mean, they are defined as follows:

  • SingleAsyncand are ToListAsyncdefined in the class EntityFrameworkQueryableExtensionsin the namespace and assembly Microsoft.EntityFrameworkCore.
  • ToAsyncEnumerabledefined in the class AsyncEnumerablein the namespace of System.Linqthe assembly System.Interactive.Async.

When a query is executed against an EF-Core, are the calls ToAsyncEnumerable().Single()/ToList()compared to SingleAsync()/ToListAsync()equivalent in function and performance? If not, how do they differ?

+4
source share
3 answers

For a returning sequence of methods (e.g. ToListAsync, ToArrayAsync), I do not expect a difference.

( First, FirstOrDefault, Single, Min, Max, Sum ..) . , , IQueryable<T> vs IEnumerable<T>. , , .

, EF Core , IQueryable<T>, , IEnumerable<T> , , , LINQ.

P.S. . IQueryable IQueryProvider ( System.Linq System.Core.dll) > Execute. , EF Core custom IAsyncQueryProvider ( Microsoft.EntityFrameworkCore.Query.Internal Microsoft.EntityFrameworkCore.dll). , , / BCL , .

+4

DbSet, ToAsyncEnumerable().Single() , SingleAsync() , . , , . SQL:

SingleAsync():
    SELECT TOP(2) [l].[ID]
    FROM [Ls] AS [l]

ToAsyncEnumerable().Single():
    SELECT [l].[ID]
    FROM [Ls] AS [l]

ToAsyncEnumerable() IQueryable LINQ-to-Objects. . , . :

ToAsyncEnumerable().Single( l => l.Something == "foo" ):
    SELECT [l].[ID], [l].[Something]
    FROM [Ls] AS [l]

:

Where( l => l.Something == "foo" ).ToAsyncEnumerable().Single():
    SELECT [l].[ID], [l].[Something]
    FROM [Ls] AS [l]
    WHERE [l].[Something] = N'foo'

, , , , :

using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query.Internal;

static class Extensions
{
    public static Task<T> SingleAsync<T>( this IQueryable<T> source ) =>
        source.Provider is IAsyncQueryProvider
            ? EntityFrameworkQueryableExtensions.SingleAsync( source )
            : Task.FromResult( source.Single() );
}
+1

Single ( 90).
, ( ).

        using (var e = source.GetEnumerator())
        {
            if (!await e.MoveNext(cancellationToken)
                        .ConfigureAwait(false))
            {
                throw new InvalidOperationException(Strings.NO_ELEMENTS);
            }
            var result = e.Current;
            if (await e.MoveNext(cancellationToken)
                       .ConfigureAwait(false))
            {
                throw new InvalidOperationException(Strings.MORE_THAN_ONE_ELEMENT);
            }
            return result;
        }

, ( ), , Ix .

SingleAsync, , , ( ), Ix Single.

0

Source: https://habr.com/ru/post/1660561/


All Articles