从 'VisitLambda' 调用时,重写类型 'System.Linq.Expressions.ParameterExpression' 的节点必须 return 相同类型的非空值
When called from 'VisitLambda', rewriting a node of type 'System.Linq.Expressions.ParameterExpression' must return a non-null value of the same type
我将我的数据层类库项目从 .NETCore 2.2 升级到 .NETCore3.1,并将 EntityFrameWork Core 等 Nuget 包从 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();
}
错误:
When called from 'VisitLambda', rewriting a node of type 'System.Linq.Expressions.ParameterExpression' must return a non-null value of the same type. Alternatively, override 'VisitLambda' and change it to not visit children of this type.
---> System.InvalidOperationException: When called from 'VisitLambda', rewriting a node of type 'System.Linq.Expressions.ParameterExpression' must return a non-null value of the same type. Alternatively, override 'VisitLambda' and change it to not visit children of this type.
at System.Linq.Expressions.ExpressionVisitor.VisitAndConvert[T](T node, String callerName)
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitParameters(ExpressionVisitor visitor, IParameterProvider nodes, String callerName)
at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.Visit(Expression expression)
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.VisitMember(MemberExpression memberExpression)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.VisitMemberAssignment(MemberAssignment memberAssignment)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.VisitMemberInit(MemberInitExpression memberInitExpression)
at System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor visitor)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.Translate(SelectExpression selectExpression, Expression expression)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosQueryableMethodTranslatingExpressionVisitor.TranslateSelect(ShapedQueryExpression source, LambdaExpression selector)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0`1.<ExecuteAsync>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at Author.Query.Persistence.CountryService.GetCountriesDataAsync(Int32 languageId) in /src/QueryStack/Author.Query.Persistence/CountryService.cs:line 243
at Author.Query.Persistence.CountryService.GetCountriesAsync(Int32 dftLanguageId, Int32 localeLangId) in /src/QueryStack/Author.Query.Persistence/CountryService.cs:line 228
at Author.Query.Persistence.CountryService.GetAllCountriesAsync(LanguageDTO language) in /src/QueryStack/Author.Query.Persistence/CountryService.cs:line 164
at GraphQL.DataLoader.DataLoaderBase`1.DispatchAsync(CancellationToken cancellationToken)
at Author.Query.New.API.GraphQL.Resolvers.CountriesResolver.<>c__DisplayClass5_1.<<Resolve>b__3>d.MoveNext() in /src/QueryStack/Author.Query.New.API/GraphQL/Resolvers/CountriesResolver.cs:line 40
--- End of stack trace from previous location where exception was thrown ---
at GraphQL.Types.ResolveFieldContext`1.TryAsyncResolve[TResult](Func`2 resolve, Func`2 error)
--- End of inner exception stack trace ---
任何人都可以通过提供解决此问题的指导来帮助我吗?
这里有几个问题很容易解决,将查询分成两半,第一部分查询数据库,return 部分填充的 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());
}
我创建了一个匿名类型来保存数据库中的 return,而不是向 DTO 添加附加字段以获取图像 ID 等。
如果您需要数据库中的更多内容,只需将字段添加到上下文 select 语句中的匿名类型即可。
这个错误刚刚发生在我身上,对于未来的访客来说,这是我做错了什么:
我有两个模型,例如:
public User
{
public int Id {get; set;}
public string Name {get; set;}
//just a silly method that does something
public string GetName()
{
return this.Name + "something"
}
}
public UserInfo
{
public int Id {get; set;}
// a bunch of other properties
}
在代码的某个地方,我用自动映射器做了一个投影,比如
Mapper.ProjectTo<UserInfo>(Repository.Get().ByUserName(userId)).FirstOrDefault();
当我插入以某种方式破坏了 projectTo 映射的 GetName
方法时,此错误 When called from 'VisitLambda',...
开始显示。
我将我的数据层类库项目从 .NETCore 2.2 升级到 .NETCore3.1,并将 EntityFrameWork Core 等 Nuget 包从 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();
}
错误:
When called from 'VisitLambda', rewriting a node of type 'System.Linq.Expressions.ParameterExpression' must return a non-null value of the same type. Alternatively, override 'VisitLambda' and change it to not visit children of this type.
---> System.InvalidOperationException: When called from 'VisitLambda', rewriting a node of type 'System.Linq.Expressions.ParameterExpression' must return a non-null value of the same type. Alternatively, override 'VisitLambda' and change it to not visit children of this type.
at System.Linq.Expressions.ExpressionVisitor.VisitAndConvert[T](T node, String callerName)
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitParameters(ExpressionVisitor visitor, IParameterProvider nodes, String callerName)
at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.Visit(Expression expression)
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.VisitMember(MemberExpression memberExpression)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.VisitMemberAssignment(MemberAssignment memberAssignment)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.VisitMemberInit(MemberInitExpression memberInitExpression)
at System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor visitor)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosProjectionBindingExpressionVisitor.Translate(SelectExpression selectExpression, Expression expression)
at Microsoft.EntityFrameworkCore.Cosmos.Query.Internal.CosmosQueryableMethodTranslatingExpressionVisitor.TranslateSelect(ShapedQueryExpression source, LambdaExpression selector)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0`1.<ExecuteAsync>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at Author.Query.Persistence.CountryService.GetCountriesDataAsync(Int32 languageId) in /src/QueryStack/Author.Query.Persistence/CountryService.cs:line 243
at Author.Query.Persistence.CountryService.GetCountriesAsync(Int32 dftLanguageId, Int32 localeLangId) in /src/QueryStack/Author.Query.Persistence/CountryService.cs:line 228
at Author.Query.Persistence.CountryService.GetAllCountriesAsync(LanguageDTO language) in /src/QueryStack/Author.Query.Persistence/CountryService.cs:line 164
at GraphQL.DataLoader.DataLoaderBase`1.DispatchAsync(CancellationToken cancellationToken)
at Author.Query.New.API.GraphQL.Resolvers.CountriesResolver.<>c__DisplayClass5_1.<<Resolve>b__3>d.MoveNext() in /src/QueryStack/Author.Query.New.API/GraphQL/Resolvers/CountriesResolver.cs:line 40
--- End of stack trace from previous location where exception was thrown ---
at GraphQL.Types.ResolveFieldContext`1.TryAsyncResolve[TResult](Func`2 resolve, Func`2 error)
--- End of inner exception stack trace ---
任何人都可以通过提供解决此问题的指导来帮助我吗?
这里有几个问题很容易解决,将查询分成两半,第一部分查询数据库,return 部分填充的 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());
}
我创建了一个匿名类型来保存数据库中的 return,而不是向 DTO 添加附加字段以获取图像 ID 等。 如果您需要数据库中的更多内容,只需将字段添加到上下文 select 语句中的匿名类型即可。
这个错误刚刚发生在我身上,对于未来的访客来说,这是我做错了什么:
我有两个模型,例如:
public User
{
public int Id {get; set;}
public string Name {get; set;}
//just a silly method that does something
public string GetName()
{
return this.Name + "something"
}
}
public UserInfo
{
public int Id {get; set;}
// a bunch of other properties
}
在代码的某个地方,我用自动映射器做了一个投影,比如
Mapper.ProjectTo<UserInfo>(Repository.Get().ByUserName(userId)).FirstOrDefault();
当我插入以某种方式破坏了 projectTo 映射的 GetName
方法时,此错误 When called from 'VisitLambda',...
开始显示。