无法翻译 LINQ 表达式 DbSet<>.Any

Posted

技术标签:

【中文标题】无法翻译 LINQ 表达式 DbSet<>.Any【英文标题】:The LINQ expression DbSet<>.Any could not be translated 【发布时间】:2020-09-29 21:44:13 【问题描述】:

我正在使用 ConsmoDB 和 Entity Framework Core 3.1。 需要检查实体是否存在

bool callExists = await _context.Calls
    .AsNoTracking()
    .AnyAsync(x => x.Number == request.Number && x.CustomerId == request.CustomerId, cancellationToken);

if (callExists)

    throw new ConflictException($"Call already exists");

运行后出现如下异常

System.InvalidOperationException:LINQ 表达式 'DbSet .Any(c => c.Number == __request_Number_0 && c.CustomerId == __request_CustomerId_1)' 无法翻译。要么以可翻译的形式重写查询,要么切换到客户评估 通过插入对 AsEnumerable() 的调用,显式地 AsAsyncEnumerable()、ToList() 或 ToListAsync()。看 https://go.microsoft.com/fwlink/?linkid=2101038 了解更多信息。 在 Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.g__CheckTranslated|8_0(ShapedQueryExpression 翻译, c__DisplayClass8_0& ) 在 Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression 方法调用表达式) 在 System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor 游客) 在 System.Linq.Expressions.ExpressionVisitor.Visit(表达式节点) 在 Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](表达式 询问) 在 Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](表达式 查询,布尔异步) 在 Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase 数据库、表达式查询、IModel 模型、布尔异步) 在 Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.c__DisplayClass12_01.<ExecuteAsync>b__0() at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func1 编译器) 在 Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](对象 cacheKey,Func1 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.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable1 源,表达式表达式, CancellationToken 取消令牌) 在 Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable1 source, LambdaExpression expression, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AnyAsync[TSource](IQueryable1 源,表达式1 predicate, CancellationToken cancellationToken) at Call.Api.Handlers.CreateCallCommandHandler.Handle(CreateCallMappingCommand request, CancellationToken cancellationToken) in D:\Call.Api\Handlers\CreateCallCommandHandler.cs:line 40 at MediatR.Pipeline.RequestExceptionProcessorBehavior2.Handle(TRequest 请求,CancellationToken cancelToken,RequestHandlerDelegate1 next) at MediatR.Pipeline.RequestExceptionProcessorBehavior2.Handle(TRequest 请求,CancellationToken cancelToken,RequestHandlerDelegate1 next) at MediatR.Pipeline.RequestExceptionActionProcessorBehavior2.Handle(TRequest 请求,CancellationToken cancelToken,RequestHandlerDelegate1 next) at MediatR.Pipeline.RequestExceptionActionProcessorBehavior2.Handle(TRequest 请求,CancellationToken cancelToken,RequestHandlerDelegate1 next) at MediatR.Pipeline.RequestPostProcessorBehavior2.Handle(TRequest 请求,CancellationToken cancelToken,RequestHandlerDelegate1 next) at MediatR.Pipeline.RequestPreProcessorBehavior2.Handle(TRequest request, CancellationToken cancelToken, RequestHandlerDelegate1 next) at Call.Api.Controllers.CallsController.Create(CreateCallMappingCommand createCallMappingCommand) in D:\Call.Api\Controllers\CallsController.cs:line 52 at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask1 actionResultValueTask) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker 调用者,任务 lastTask,下一个状态,作用域范围,对象状态,布尔值 完成了) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed 语境) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& 作用域, Object& 状态, Boolean& isCompleted) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker 调用者,任务 lastTask,下一个状态,作用域范围,对象状态,布尔值 完成了) 在 Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker 调用者、任务任务、IDisposable 范围) 在 Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(端点 端点、任务 requestTask、ILogger 记录器) 在 Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext 语境) 在 Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext http上下文) 在 Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider) 在 Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext 上下文)

模型调用 公共课调用


    public Guid CallId  get; set; 

    public string Number  get; set; 

    public int CustomerId  get; set; 

    public Type Type  get; set; 

请求相同(仅没有CallId)

【问题讨论】:

能否添加类型(实体和请求)? 您可能想先尝试将 request 中的值放入局部变量中,然后使用它们,因为 EF 可能不知道如何将 request 对象转换为 SQL。 异常告诉你,使用 azure cosmos db 实体框架提供程序时,linq .Any() 方法没有翻译。 或者尝试将过滤移动到Where,然后是AsEnumerable,然后是Any 添加实体模型 【参考方案1】:

.AnyAsync 不受支持。作为替代方案,您可以使用.CountAsync() 并检查count &gt; 0

令人难以置信的是,团队会实施 .CountAsync 而不是 .AnyAsync

【讨论】:

以上是关于无法翻译 LINQ 表达式 DbSet<>.Any的主要内容,如果未能解决你的问题,请参考以下文章

带有 DbSet 的 LINQ ToListAsync 表达式

EF.Property 抛出“无法翻译 LINQ 表达式”

LINQ 表达式 - 使用 .Any in s Select 无法翻译

在 DbSet<T> 上使用 LINQ 扩展方法时调用不明确

无法翻译 LINQ 表达式“表达式”。以可以翻译的形式重写查询

LINQ 表达式“无法翻译”