При вызове из «VisitLambda» перезапись узла типа «System.Linq.Expressions.ParameterExpression» должна возвращать ненулевое значение того же типа. - PullRequest
0 голосов
/ 10 января 2020

Я обновил свой библиотечный проект уровня данных с .NETCore 2.2 до .NETCore3.1, а также обновил пакеты Nuget, такие как EntityFrameWork Core, с 2.2.0 до EFCore 3.1.0.

Я затем при проверке следующего кода получил ошибку, как указано ниже:

Код:

private async Task<List<CountryDTO>> GetCountriesDataAsync(int languageId)
{
    int pageNo = 1, pageSize = 100;
    var images = await _cacheService.GetAllAsync("imagesCacheKey");
    return await _dbContext.Countries
                    .Where(cc => cc.IsPublished.Equals(true) 
                                     && cc.LanguageId.Equals(languageId))
                    .Select(co => new CountryDTO
                            {  Uuid = co.CountryId, 
                               PNGImagePath = images.FirstOrDefault(im => im.ImageId.Equals(co.PNGImageId))
                                                    .FilePath, 
                                SVGImagePath = images.FirstOrDefault(im => im.ImageId.Equals(co.SVGImageId))
                                                    .FilePath, 
                          DisplayName = co.DisplayName, 
                          DisplayNameShort = co.DisplayName, 
                          Name = Helper.ReplaceChars(co.DisplayName), 
                          Path = Helper.ReplaceChars(co.DisplayName), 
                          CompleteResponse = true})
                   .Skip((pageNo - 1) * 100)
                   .Take(pageSize)
                   .ToListAsync();
}

Ошибка:

При вызове из «VisitLambda» перезапись узла типа «System.Linq.Expressions.ParameterExpression» должна возвращать ненулевое значение того же типа. Либо переопределите «VisitLambda» и измените его, чтобы не посещать дочерние элементы этого типа. \ N ---> System.InvalidOperationException: при вызове из «VisitLambda» перезапись узла типа «System.Linq.Expressions.ParameterExpression» должна возвращаться ненулевое значение того же типа. Также можно переопределить «VisitLambda» и изменить его, чтобы не посещать дочерние элементы этого типа. \ N в System.Linq.Expressions.ExpressionVisitor.VisitAndConvert [T] (T node, String callerName) \ n в System.Dynami c .Utils .ExpressionVisitorUtils.VisitParameters (посетитель ExpressionVisitor, узлы IParameterProvider, String callerName) \ n в System.Linq.Expressions.ExpressionVisitor.VisitLambda [T] (выражение 1 node)\n at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.Visit(Expression expression)\n at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)\n at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)\n at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)\n at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.Visit(Expression expression)\n at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.VisitMember(MemberExpression memberExpression)\n at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.Visit(Expression expression)\n at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.VisitMemberAssignment(MemberAssignment memberAssignment)\n at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.VisitMemberInit(MemberInitExpression memberInitExpression)\n at System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor visitor)\n at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.Visit(Expression expression)\n at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.Translate(SelectExpression selectExpression, Expression expression)\n at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosQueryableMethodTranslatingExpressionVisitor.TranslateSelect(ShapedQueryExpression source, LambdaExpression selector)\n at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)\n at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)\n at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)\n at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)\n at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)\n at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)\n at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0 1.b__0 () \ n в Microsoft.EntityFraeryworku. CompiledQueryCache.GetOrAddQueryCore [TFunc] (объект cacheKey, компилятор Fun c1 compiler)\n at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func 1) \ n в Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync [TResult] (запрос на выражение, CancellationToken С ion.ToListAsync [TSource] (IQueryable 1 source, CancellationToken cancellationToken)\n at Author.Query.Persistence.CountryService.GetCountriesDataAsync(Int32 languageId) in /src/QueryStack/Author.Query.Persistence/CountryService.cs:line 243\n at Author.Query.Persistence.CountryService.GetCountriesAsync(Int32 dftLanguageId, Int32 localeLangId) in /src/QueryStack/Author.Query.Persistence/CountryService.cs:line 228\n at Author.Query.Persistence.CountryService.GetAllCountriesAsync(LanguageDTO language) in /src/QueryStack/Author.Query.Persistence/CountryService.cs:line 164\n at GraphQL.DataLoader.DataLoaderBase 1.DispatchAsyn c (CancellationToken cancellationToken) \ n в Author.Query.New.API.GraphQL.Resolvers.CountriesResolver. <> c__DisplayClass5_1. d.MoveNext () в /src/QueryStack/Author.Query.New.API/GraphQL/Resolvers/CountriesResolver.cs:line 40 \ n --- Конец трассировки стека из предыдущего расположения, где было сгенерировано исключение --- \ n at GraphQL.Types.ResolveFieldContext * разрешение 1019 * 2, ошибка Func`2) \ n --- Конец внутренней трассировки стека исключений ---

Может ли кто-нибудь помочь мне, предоставив свои рекомендации исправить эту проблему

1 Ответ

4 голосов
/ 29 января 2020

У вас есть пара проблем, которые довольно легко исправить, разбить запрос на две половины: первую, чтобы запросить базу данных, и вернуть список частично заполненных CountryDTO, а вторая перебрать список, заполняющий отсутствующие элементы:

private async Task<List<CountryDTO>> GetCountriesDataAsync(int languageId)
{
            int pageNo = 1, pageSize = 100;

            var results = _dbContext.Countries // <- do not use await on db context
                    .Where(cc => cc.IsPublished.Equals(true)
                      && cc.LanguageId.Equals(languageId))
                    .Select(co => new {
                        co.CountryId,
                        co.DisplayName,
                        co.PNGImageId,
                        co.SVGImageId
                    })
                     .Skip((pageNo - 1) * pageSize) // <- use page size no 100
                     .Take(pageSize)
                     .ToListAsync();

            var images = await _cacheService.GetAllAsync("imagesCacheKey");

            return Task.FromResult( results.Select(co => new CountryDTO
            {
                Uuid = co.CountryId,
                PNGImagePath = images.FirstOrDefault(im => im.ImageId.Equals(co.PNGImageId))?.FilePath, // <- could be null so use ?.FilePath
                SVGImagePath = images.FirstOrDefault(im => im.ImageId.Equals(co.SVGImageId))?.FilePath,
                DisplayName = co.DisplayName,
                DisplayNameShort = co.DisplayName,
                Name = Helper.ReplaceChars(co.DisplayName),
                Path = Helper.ReplaceChars(co.DisplayName),
                CompleteResponse = true
            }).ToList());

}

Я создал анонимный тип для хранения возврата из базы данных, в отличие от добавления дополнительного поля в DTO для идентификаторов изображений и тому подобного. если вам нужно больше из базы данных, просто добавьте поля к анонимному типу в операторе выбора контекста.

...