zzzprojects / EntityFramework-Plus

Entity Framework Plus extends your DbContext with must-haves features: Include Filter, Auditing, Caching, Query Future, Batch Delete, Batch Update, and more
https://entityframework-plus.net/
MIT License
2.27k stars 318 forks source link

The underlying reader doesn't have as many fields as expected. Expected: 18, actual: 0. #816

Closed radek673 closed 1 week ago

radek673 commented 1 week ago

Here is what to include in your request to make sure we implement a solution as quickly as possible.

1. Description

I have the following code:

using Microsoft.EntityFrameworkCore;
using Tools.Data;
using Z.EntityFramework.Plus;

namespace Iam.Data.Repositories
{
    internal static class Testing
    {
        public static async Task<TPaged> ToPageAsync2<T, TPaged>(this IQueryable<T> query, IPagedSearch pagedSearch, QueryDeferred<int> totalCount)
            where T : class
            where TPaged : PagedResult<T>, new()
        {
            var page = Math.Max(0, pagedSearch.Page.GetValueOrDefault() - 1);
            var pageSize = Math.Min(100, Math.Max(5, pagedSearch.PerPage ?? 10));

            var countFuture = totalCount
                .FutureValue();

            //var queryFuture = query
            //    .Skip(page * pageSize)
            //    .Take(pageSize)
            //    .Future();

            var items = await query
                .Skip(page * pageSize)
                .Take(pageSize)
                .ToListAsync();

            return new TPaged()
            {
                Items = items,
                //Items = await queryFuture.ToListAsync(),
                TotalCount = await countFuture.ValueAsync(),
                PageIndex = page + 1,
                PageSize = pageSize,
            };
        }
    }
}

-- EF+ Query Future: 2 of 2 SELECT [u].[Id], [u].[Created], [u].[CreatedBy], [u].[Email], [u].[FirstName], [u].[Language], [u].[LastLoggedIn], [u].[LastName], [u].[Login], [u].[Name], [u].[Password], [u].[Status], [u].[Updated], [u].[UpdatedBy] FROM [User] AS [u] ORDER BY [u].[Email], [u].[Id] OFFSET @Z_2_p_0 ROWS FETCH NEXT @Z2p_1 ROWS ONLY ;

',N'@Z_2_p_0 int,@Z2p_1 int',@Z_2_p_0=0,@Z2p_1=20

- table has this structure (MSSQL) and contains 1 record:

CREATE TABLE [dbo].[User]( [Id] [int] IDENTITY(1,1) NOT NULL, [Login] varchar NOT NULL, [FirstName] nvarchar NULL, [LastName] nvarchar NULL, [Name] nvarchar NULL, [Email] varchar NOT NULL, [Password] varchar NULL, [Created] datetime2 NOT NULL, [CreatedBy] [int] NOT NULL, [Updated] datetime2 NOT NULL, [UpdatedBy] [int] NOT NULL, [LastLoggedIn] datetime2 NULL, [Status] [int] NOT NULL, [Language] [int] NOT NULL, CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED )



## 2. Exception
fail: Microsoft.EntityFrameworkCore.Query[10100]
      An exception occurred while iterating over the results of a query for context type 'Iam.Data.AppDbContext'.
      System.InvalidOperationException: The underlying reader doesn't have as many fields as expected. Expected: 18, actual: 0.
         at Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.BufferedDataRecord.InitializeFields()
         at Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.BufferedDataRecord.Initialize(DbDataReader reader, IReadOnlyList`1 columns)
         at Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.Initialize(IReadOnlyList`1 columns)
         at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.<PopulateSplitIncludeCollection>g__InitializeReader|25_1[TIncludingEntity,TIncludedEntity](RelationalQueryContext queryContext, RelationalCommandResolver relationalCommandResolver, IReadOnlyList`1 readerColumns, Boolean detailedErrorsEnabled)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.<>c__25`2.<PopulateSplitIncludeCollection>b__25_0(ValueTuple`4 tup)
         at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.<>c__DisplayClass12_0`2.<Execute>b__0(DbContext _, TState s)
         at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
         at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute[TState,TResult](IExecutionStrategy strategy, TState state, Func`2 operation, Func`2 verifySucceeded)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.PopulateSplitIncludeCollection[TIncludingEntity,TIncludedEntity](Int32 collectionId, RelationalQueryContext queryContext, IExecutionStrategy executionStrategy, RelationalCommandResolver relationalCommandResolver, IReadOnlyList`1 readerColumns, Boolean detailedErrorsEnabled, SplitQueryResultCoordinator resultCoordinator, Func`3 childIdentifier, IReadOnlyList`1 identifierValueComparers, Func`5 innerShaper, Action`3 relatedDataLoaders, INavigationBase inverseNavigation, Action`2 fixup, Boolean trackingQuery)
         at lambda_method711(Closure, QueryContext, IExecutionStrategy, SplitQueryResultCoordinator)
         at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable`1.Enumerator.MoveNext()
      System.InvalidOperationException: The underlying reader doesn't have as many fields as expected. Expected: 18, actual: 0.
         at Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.BufferedDataRecord.InitializeFields()
         at Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.BufferedDataRecord.Initialize(DbDataReader reader, IReadOnlyList`1 columns)
         at Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.Initialize(IReadOnlyList`1 columns)
         at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.<PopulateSplitIncludeCollection>g__InitializeReader|25_1[TIncludingEntity,TIncludedEntity](RelationalQueryContext queryContext, RelationalCommandResolver relationalCommandResolver, IReadOnlyList`1 readerColumns, Boolean detailedErrorsEnabled)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.<>c__25`2.<PopulateSplitIncludeCollection>b__25_0(ValueTuple`4 tup)
         at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.<>c__DisplayClass12_0`2.<Execute>b__0(DbContext _, TState s)
         at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
         at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute[TState,TResult](IExecutionStrategy strategy, TState state, Func`2 operation, Func`2 verifySucceeded)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.PopulateSplitIncludeCollection[TIncludingEntity,TIncludedEntity](Int32 collectionId, RelationalQueryContext queryContext, IExecutionStrategy executionStrategy, RelationalCommandResolver relationalCommandResolver, IReadOnlyList`1 readerColumns, Boolean detailedErrorsEnabled, SplitQueryResultCoordinator resultCoordinator, Func`3 childIdentifier, IReadOnlyList`1 identifierValueComparers, Func`5 innerShaper, Action`3 relatedDataLoaders, INavigationBase inverseNavigation, Action`2 fixup, Boolean trackingQuery)
         at lambda_method711(Closure, QueryContext, IExecutionStrategy, SplitQueryResultCoordinator)
         at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable`1.Enumerator.MoveNext()
fail: Tools.Middlewares.LogExceptionsMiddleware[0]
      Unhandled exception.
      System.InvalidOperationException: The underlying reader doesn't have as many fields as expected. Expected: 18, actual: 0.
         at Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.BufferedDataRecord.InitializeFields()
         at Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.BufferedDataRecord.Initialize(DbDataReader reader, IReadOnlyList`1 columns)
         at Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.Initialize(IReadOnlyList`1 columns)
         at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.<PopulateSplitIncludeCollection>g__InitializeReader|25_1[TIncludingEntity,TIncludedEntity](RelationalQueryContext queryContext, RelationalCommandResolver relationalCommandResolver, IReadOnlyList`1 readerColumns, Boolean detailedErrorsEnabled)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.<>c__25`2.<PopulateSplitIncludeCollection>b__25_0(ValueTuple`4 tup)
         at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.<>c__DisplayClass12_0`2.<Execute>b__0(DbContext _, TState s)
         at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
         at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute[TState,TResult](IExecutionStrategy strategy, TState state, Func`2 operation, Func`2 verifySucceeded)
         at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.PopulateSplitIncludeCollection[TIncludingEntity,TIncludedEntity](Int32 collectionId, RelationalQueryContext queryContext, IExecutionStrategy executionStrategy, RelationalCommandResolver relationalCommandResolver, IReadOnlyList`1 readerColumns, Boolean detailedErrorsEnabled, SplitQueryResultCoordinator resultCoordinator, Func`3 childIdentifier, IReadOnlyList`1 identifierValueComparers, Func`5 innerShaper, Action`3 relatedDataLoaders, INavigationBase inverseNavigation, Action`2 fixup, Boolean trackingQuery)
         at lambda_method711(Closure, QueryContext, IExecutionStrategy, SplitQueryResultCoordinator)
         at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable`1.Enumerator.MoveNext()
         at Z.EntityFramework.Plus.QueryFutureEnumerable`1.SetResult(IEnumerator`1 enumerator)
         at Z.EntityFramework.Plus.QueryFutureEnumerable`1.SetResult(DbDataReader reader)
         at Z.EntityFramework.Plus.QueryFutureBatch.ExecuteQueriesAsync(CancellationToken cancellationToken)
         at Z.EntityFramework.Plus.QueryFutureEnumerable`1.ToListAsync(CancellationToken cancellationToken)
         at Tools.Data.QueryableExtensions.ToPageAsync[T,TPaged](IQueryable`1 query, IPagedSearch pagedSearch, QueryDeferred`1 totalCount)
         at Tools.Data.QueryableExtensions.ToPageAsync[T](IQueryable`1 query, IPagedSearch pagedSearch, QueryDeferred`1 totalCount)
         at Iam.Data.Repositories.UserRepository.Search(IUserPagedSearch searchData) in C:\Work\IAM\src\Iam.Data\Repositories\UserRepository.cs:line 100
         at Iam.Business.Security.UserService.Search(IUserPagedSearch searchData) in C:\Work\IAM\src\Iam.Business\Services\UserService.cs:line 134

## 3. Fiddle or Project

## 4. Any further technical details
- not sure, happening always with certain tables/queries, other tables/queries are fine

### Further technical details

- EF version: [Microsoft.EntityFrameworkCore.SqlServer 9.0.0]
- EF Plus version: [Z.EntityFramework.Plus.EFCore 9.103.6.2]
- Database Server version: [SQL Server 2022]
- Database Provider version (NuGet): [Microsoft.Data.SqlClient v5.1.6]
- 
JonathanMagnan commented 1 week ago

Hello @radek673

Do you think you could create a runnable project with the issue? It doesn’t need to be your project, just a new solution with the minimum code to reproduce the issue.

At this moment, we have a lot of information but not enough to reproduce it. This is the first time we saw this The underlying reader doesn't have as many fields as expected. Expected: 18, actual: 0. error and the code you provided is very standard, so we have no clue how to reproduce it.

You can send the project in private here if needed: info@zzzprojects.com

Best Regards,

Jon

radek673 commented 1 week ago

Yes you are right it turned out that in this case the queryable also contained ".AsSplitQuery()" :) lesson learnt :) Best Regards, Radek

radek673 commented 1 week ago

we can also see it from the exception... "SplitQueryResultCoordinator" it says...

JonathanMagnan commented 1 week ago

Awesome, thank you for letting us know.

We will close it as soon as you find out about the problem. Indeed, our library is not compatible with this method

Best Regards,

Jon