[CSHARP-3911] LINQ3: OrderBy/OrderByDescending with expression throws ExpressionNotSupportedException Created: 18/Oct/21  Updated: 27/Oct/23  Resolved: 18/Oct/21

Status: Closed
Project: C# Driver
Component/s: LINQ3
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Unknown
Reporter: Alexey Anohin Assignee: Robert Stam
Resolution: Works as Designed Votes: 0
Labels: LINQ
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
duplicates CSHARP-3965 OrderBy with an expression that doesn... Closed

 Description   

 

var utcNow = DateTime.UtcNow; 
... 
var query = GetCollection<TEntity>().AsQueryable().Where(n => !n.StartDateUtc.HasValue || n.StartDateUtc <= utcNow);
query = query.Where(n => !n.EndDateUtc.HasValue || n.EndDateUtc >= utcNow); 
query.OrderByDescending(n => n.StartDateUtc ?? n.CreatedOnUtc);
...
query.Count();

 

Exception has occurred: CLR/MongoDB.Driver.Linq.Linq3Implementation.ExpressionNotSupportedExceptionAn exception of type 'MongoDB.Driver.Linq.Linq3Implementation.ExpressionNotSupportedException' occurred in MongoDB.Driver.dll but was not handled in user code: 'Expression not supported: n => (n.StartDateUtc ?? n.CreatedOnUtc).'   at MongoDB.Driver.Linq.Linq3Implementation.Misc.LambdaExpressionExtensions.GetFieldPath(LambdaExpression fieldSelectorLambda, TranslationContext context, IBsonSerializer parameterSerializer)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToPipelineTranslators.OrderByMethodToPipelineTranslator.CreateSortField(TranslationContext context, String methodName, LambdaExpression keySelector, IBsonSerializer parameterSerializer)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToPipelineTranslators.OrderByMethodToPipelineTranslator.Translate(TranslationContext context, MethodCallExpression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToPipelineTranslators.ExpressionToPipelineTranslator.Translate(TranslationContext context, Expression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToExecutableQueryTranslators.CountMethodToExecutableQueryTranslator.Translate[TDocument](MongoQueryProvider`1 provider, TranslationContext context, MethodCallExpression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToExecutableQueryTranslators.ExpressionToExecutableQueryTranslator.TranslateScalar[TDocument,TResult](MongoQueryProvider`1 provider, Expression expression)
   at MongoDB.Driver.Linq.Linq3Implementation.MongoQueryProvider`1.Execute[TResult](Expression expression)
   at System.Linq.Queryable.Count[TSource](IQueryable`1 source)



 Comments   
Comment by Robert Stam [ 18/Oct/21 ]

Thank you for trying the beta version of the new LINQ provider and for reporting this issue.

The issue is not with Count but rather with a server side limitation that $sort only allows sorting on fields, not on arbitrary expressions.

So the argument to OrderByDescending must be an Expression that translates to a field reference.

You can work around this server limitation by creating a temporary field to sort on, like this:

 var queryable = collection.AsQueryable()
    .Where(n => !n.StartDateUtc.HasValue || n.StartDateUtc <= utcNow)
    .Where(n => !n.EndDateUtc.HasValue || n.EndDateUtc >= utcNow)
    .Select(n => new { OriginalDocument = n, TempOrderByField = n.StartDateUtc ?? n.CreatedOnUtc })
    .OrderByDescending(n => n.TempOrderByField)
    .Select(n => n.OriginalDocument);

Generated at Wed Feb 07 21:46:39 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.