带有 OrderBy 的 EF 查询失败

Fra*_*k B 2 c# linq entity-framework entity-framework-core

我确信对此有一个简单的答案,但我似乎无法确定。

我有以下代码,

internal override async Task FetchDataModel()
{
    var dateCutoff = DateTime.Today.AddDays(-PeriodInDays);

     var query = this.DB.Jobs
         .IsDelivered()
         .Where(x => x.DeliveredTime.Value.Date >= dateCutoff)
         .GroupBy(x => new { x.Pet.OwnerId, x.Pet.Owner.First, x.Pet.Owner.Last })
         .Select(x => new MVPCustomerDTO
         {
             OwnerId = x.Key.OwnerId,
             OwnerName = $"{x.Key.First} {x.Key.Last}",
             JobCount = x.Count(),
             TotalSpend = x.Sum(a => (a.Price ?? 0M) - a.Discount) 
                      + this.DB.JobExtras
                               .Where(a => a.Job.Pet.OwnerId == x.Key.OwnerId)
                               .Where(a => a.Job.DeliveredTime.Value.Date >= dateCutoff)
                               .Sum(a => a.Price),
         })
/*==>Problem Line*/ .OrderByDescending(x => x.TotalSpend)
         .Take(25);

          var result = await query
                      .ToListAsync()
                      .ConfigureAwait(false);

          this.Model = result;
}
Run Code Online (Sandbox Code Playgroud)

我不知道如何解决这个异常。它的 EF 核心 3.0 代码。OrderByDescending 导致了这个问题。如果我将其删除,则查询有效。我想这可能与 TotalSpend 有关,所以我试图解决这个问题,我删除了 TotalSpend 字段,并将 OrderByDescending 更改为 orderby JobCount,并得到了相同的结果。我确定这与服务器端翻译有关,但我似乎无法解决这个问题来解决这个问题。

请帮我看灯!?!

抛出的异常是:

 System.ArgumentNullException: Value cannot be null. (Parameter 'key')
    at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
    at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
    at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SelectExpression.GetMappedProjection(ProjectionMember projectionMember)
    at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitExtension(Expression extensionExpression)
    at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.Translate(Expression expression)
    at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateExpression(Expression expression)
    at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateLambdaExpression(ShapedQueryExpression shapedQueryExpression, LambdaExpression lambdaExpression)
    at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateOrderBy(ShapedQueryExpression source, LambdaExpression keySelector, Boolean ascending)
    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__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 GroomShop.Web.ReportGenerators.MVPCustomerReport.FetchDataModel() in C:\Workspace\GroomShop\GroomShop.Web\ReportGenerators\MVPCustomerReport.cs:line 203
Run Code Online (Sandbox Code Playgroud)

Iva*_*oev 5

该例外具有误导性。问题是投影 ( Select) 中的内插字符串当然不能转换为 SQL 并且应该生成客户端评估异常告诉您。相反(很可能是 EF Core 实现错误),您会收到上述误导性异常。

解决方案当然是避免不可翻译的构造/方法,如内插字符串,Format/ToString带有格式字符串/文化信息参数的方法。相反,使用字符串连接(ToString如果需要,使用无参数方法),例如替换

OwnerName = $"{x.Key.First} {x.Key.Last}",
Run Code Online (Sandbox Code Playgroud)

OwnerName = x.Key.First + " " + x.Key.Last,
Run Code Online (Sandbox Code Playgroud)