C# 带有OrderBy的EF查询失败
我相信有一个简单的答案,但我似乎无法确定 我有以下代码C# 带有OrderBy的EF查询失败,c#,entity-framework,linq,entity-framework-core,C#,Entity Framework,Linq,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 >= da
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;
}
我不知道如何避开这个异常。其EF核心3.0代码。OrderByDescending导致了问题。如果我删除它,查询就会工作。我认为这可能与TotalExpense有关,所以我试图绕开它,删除了TotalExpense字段,将OrderByDescending更改为OrderByJobCount,得到了相同的结果。我确信这与服务器端翻译有关,但我似乎无法用头脑来解决这个问题
请帮我看看灯
抛出的异常是:
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
System.ArgumentNullException:值不能为null。(参数“key”)
at System.Collections.Generic.Dictionary`2.FindEntry(TKey)
在System.Collections.Generic.Dictionary`2.get_项(TKey)
在Microsoft.EntityFrameworkCore.Query.SqlExpressions.SelectExpression.GetMappedProjection(ProjectionMember ProjectionMember)
位于Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisiTexttension(表达式扩展Expression)
位于Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.Translate(表达式)
在Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslationExpressionVisitor.TranslateExpression(表达式)中
在Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslationExpressionVisitor.TranslateLambdaExpression(ShapedQueryExpression ShapedQueryExpression,LambdaExpression LambdaExpression)
位于Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslationExpressionVisitor.TranslateOrderBy(ShapedQueryExpression源、LambdaExpression键选择器、布尔升序)
在Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslationExpressionVisitor.VisitMethodCall调用(MethodCallExpression MethodCallExpression)
位于Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslationExpressionVisitor.VisitMethodCallExpression(MethodCallExpression MethodCallExpression)
位于System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor)
在Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslationExpressionVisitor.VisitMethodCall调用(MethodCallExpression MethodCallExpression)
位于Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslationExpressionVisitor.VisitMethodCallExpression(MethodCallExpression MethodCallExpression)
位于System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor)
位于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__显示Class12_0`1.b__0()
位于Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](对象缓存键,Func`1编译器)
位于Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOradQuery[TResult](对象缓存键,Func`1编译器)
在Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](表达式查询,取消令牌取消令牌)
在Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](表达式表达式,CancellationToken CancellationToken)
位于Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken CancellationToken)
在System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()中
位于Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListSync[TSource](IQueryable`1源,CancellationToken CancellationToken)
在C:\Workspace\GroomShop\GroomShop.Web\ReportGenerators\MVPCustomerReport.FetchDataModel()中的GroomShop.Web.ReportGenerators.MVPCustomerReport.cs:第203行
查询失败的原因可能是Jobs.Pet
或Jobs.Pet.Owner
在某些数据库条目中为空
然后在LINQ
Select()
中访问x.Key.OwnerId
或x.Key.First
或x.Key.Last
时,它将抛出异常该异常具有误导性。问题是投影(Select
)中的插值字符串,它当然不能转换为SQL,应该会生成客户端计算异常,告诉您这一点。相反(最有可能是EF核心实现错误),您会得到上述误导性异常
当然,解决方案是避免不可翻译的构造/方法,如插入字符串、Format
/ToString
方法和格式字符串/区域性信息参数。相反,使用字符串连接(以及无参数的ToString
方法,如果需要),例如替换
OwnerName = $"{x.Key.First} {x.Key.Last}",
与
当查询使用OrderByDescending()时,查询查看的行比只查看顶部(25)的行更多。OrderBy必须点击所有有问题的行才能进行排序。一种可能性是,您很幸运,最上面(25)行没有碰到任何空值
如果是这种情况,则必须处理空值,或者从查询中排除空值,具体取决于需求。否则,就会有别的事情发生。只是好奇而已。。。您的查询是否有可用的SQL版本?如果是,你能分享吗?我经常发现,在LINQ中创建复杂查询时,如果我有一个可以运行的SQL查询来构建,它会变得更容易。请为Pet.Owner添加Include。我猜,x.Key.First可能是空的。伊万有答案。。这是字符串插值。奇怪的是,如果
OwnerName = x.Key.First + " " + x.Key.Last,