[英]Generic expression for EF Core 3.1 filtering throws exception on .Any(…)
[英]EF Core 3.1 throws an exception for Contains
我最近将项目代码更新为 .NET Core 3.1 和 EF Core 3.1,现在我的大部分 linq 查询都停止了,EX。
public override ICollection<ContactDetailModel> GetAll(ICollection<int> ids)
{
return _context
.Set<TEntity>()
.IgnoreDeletedEntities()
.Where(x => ids.Distinct().Contains(x.ContactId))
.Select(EntityToDTOMapper)
.ToList();
}
这段代码在我使用 contains 的地方抛出了一个错误,我在其他一些帖子中看到这个问题已被修复为一个错误,但它仍然失败。
我得到的错误是“无法翻译。要么以可以翻译的形式重写查询,要么通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估.”
System.InvalidOperationException
HResult=0x80131509
Message=The LINQ expression 'DbSet<SupplierContactDetails>
.Where(s => !(s.DeletedOn.HasValue) && !(s.DeletedBy.HasValue))
.Where(s => __Distinct_0
.Contains(s.ContactId))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
Source=Microsoft.EntityFrameworkCore
StackTrace:
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.<VisitMethodCall>g__CheckTranslated|8_0(ShapedQueryExpression translated, <>c__DisplayClass8_0& )
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
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__DisplayClass9_0`1.<Execute>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.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at BlueTag.DAL.Repositories.ContactRepository`1.GetAll(ICollection`1 ids) in D:\Projects\BlueTag Version 2\.net-core-server\DAL\Repositories\ContactRepository.cs:line 95
at BlueTag.DAL.Repositories.SupplierRepository.ToDomain(IEnumerable`1 supplier) in D:\Projects\BlueTag Version 2\.net-core-server\DAL\Repositories\SupplierRepository.cs:line 216
at BlueTag.DAL.Repositories.SupplierRepository.GetFilteredSuppliers(RequestPagingOptionsModel`1 options) in D:\Projects\BlueTag Version 2\.net-core-server\DAL\Repositories\SupplierRepository.cs:line 129
at BlueTag.Supplier.Services.SupplierService.GetFilteredSupplierDetails(RequestPagingOptionsModel`1 options) in D:\Projects\BlueTag Version 2\.net-core-server\Supplier\Serrvices\SupplierService.cs:line 49
at BlueTag.Supplier.Controllers.SupplierController.GetFilteredSuppliers(RequestPagingOptionsModel`1 options) in D:\Projects\BlueTag Version 2\.net-core-server\Supplier\Controllers\SupplierController.cs:line 54
at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
Entity Framework 无法转换每个查询,因此它有时必须加载所有数据并在内存中执行 LINQ 表达式,这称为客户端评估,这是不可取的,因为它占用更多资源并且需要更长的时间。 对于您的特定问题,有 2 种解决方案,错误消息中概述了这两种解决方案。
1) 重写您的 LINQ 查询以包括对客户端评估的显式调用与隐式调用
或者
2) 重写您的 LINQ 查询以不需要客户端评估
你可以像这样做 1 号:
public override ICollection<ContactDetailModel> GetAll(ICollection<int> ids)
{
return _context
.Set<TEntity>()
.IgnoreDeletedEntities()
.ToList()
.Where(x => ids.Distinct().Contains(x.ContactId))
.Select(EntityToDTOMapper)
.ToList();
}
请注意在IgnoreDeletedEntities
之后对ToList
的显式调用,需要这样做以显式切换到客户端评估,以便您的Where
语句将正确执行并且不会抛出任何错误。 这是因为x => ids.Distinct().Contains(x.ContactId)
无法通过您的 EF 版本转换为 SQL(或其他)。
2号可以这样解决:
public override ICollection<ContactDetailModel> GetAll(ICollection<int> ids)
{
ids = ids.Distinct();
return _context
.Set<TEntity>()
.IgnoreDeletedEntities()
.Where(x => ids.Contains(x.ContactId))
.Select(EntityToDTOMapper)
.ToList();
}
请注意我如何将ids.Distinct()
的使用从Where
移到顶部,因为那是 EF 无法翻译的部分
最近,我将项目代码更新为.NET Core 3.1和EF Core 3.1,现在我的大多数linq查询都是EX。
public override ICollection<ContactDetailModel> GetAll(ICollection<int> ids)
{
return _context
.Set<TEntity>()
.IgnoreDeletedEntities()
.Where(x => ids.Distinct().Contains(x.ContactId))
.Select(EntityToDTOMapper)
.ToList();
}
这段代码在我使用“包含”的地方引发了错误,我在其他一些帖子中看到此问题已作为错误得到修复,但失败了。
我收到的错误是“无法翻译。要么以可以翻译的形式重写查询,要么通过插入对AsEnumerable(),AsAsyncEnumerable(),ToList()或ToListAsync()的调用来显式切换到客户端评估。”
System.InvalidOperationException
HResult=0x80131509
Message=The LINQ expression 'DbSet<SupplierContactDetails>
.Where(s => !(s.DeletedOn.HasValue) && !(s.DeletedBy.HasValue))
.Where(s => __Distinct_0
.Contains(s.ContactId))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
Source=Microsoft.EntityFrameworkCore
StackTrace:
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.<VisitMethodCall>g__CheckTranslated|8_0(ShapedQueryExpression translated, <>c__DisplayClass8_0& )
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
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__DisplayClass9_0`1.<Execute>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.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at BlueTag.DAL.Repositories.ContactRepository`1.GetAll(ICollection`1 ids) in D:\Projects\BlueTag Version 2\.net-core-server\DAL\Repositories\ContactRepository.cs:line 95
at BlueTag.DAL.Repositories.SupplierRepository.ToDomain(IEnumerable`1 supplier) in D:\Projects\BlueTag Version 2\.net-core-server\DAL\Repositories\SupplierRepository.cs:line 216
at BlueTag.DAL.Repositories.SupplierRepository.GetFilteredSuppliers(RequestPagingOptionsModel`1 options) in D:\Projects\BlueTag Version 2\.net-core-server\DAL\Repositories\SupplierRepository.cs:line 129
at BlueTag.Supplier.Services.SupplierService.GetFilteredSupplierDetails(RequestPagingOptionsModel`1 options) in D:\Projects\BlueTag Version 2\.net-core-server\Supplier\Serrvices\SupplierService.cs:line 49
at BlueTag.Supplier.Controllers.SupplierController.GetFilteredSuppliers(RequestPagingOptionsModel`1 options) in D:\Projects\BlueTag Version 2\.net-core-server\Supplier\Controllers\SupplierController.cs:line 54
at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.