/// <summary> /// Modifies the current sort stage by appending a descending field specification to it. /// </summary> /// <typeparam name="TResult">The type of the result.</typeparam> /// <param name="aggregate">The aggregate.</param> /// <param name="field">The field to sort by.</param> /// <returns> /// The fluent aggregate interface. /// </returns> public static IOrderedAggregateFluent <TResult> ThenByDescending <TResult>(this IOrderedAggregateFluent <TResult> aggregate, Expression <Func <TResult, object> > field) { Ensure.IsNotNull(aggregate, "aggregate"); Ensure.IsNotNull(field, "field"); // this looks sketchy, but if we get here and this isn't true, then // someone is being a bad citizen. var lastStage = aggregate.Stages.Last(); aggregate.Stages.RemoveAt(aggregate.Stages.Count - 1); // remove it so we can add it back var stage = new DelegatedPipelineStageDefinition <TResult, TResult>( "$sort", (s, sr) => { var lastSort = lastStage.Render(s, sr).Document["$sort"].AsBsonDocument; var newSort = new DirectionalSortDefinition <TResult>(new ExpressionFieldDefinition <TResult>(field), SortDirection.Descending).Render(s, sr); return(new RenderedPipelineStageDefinition <TResult>("$sort", new BsonDocument("$sort", lastSort.Merge(newSort)), s)); }); return((IOrderedAggregateFluent <TResult>)aggregate.AppendStage(stage)); }
Order <T>(IOrderedAggregateFluent <T> source) { return(source.ThenByDescending(Property.QueryFrom <T>())); }
/// <summary> /// Modifies the current sort stage by appending a descending field specification to it. /// </summary> /// <typeparam name="TResult">The type of the result.</typeparam> /// <param name="aggregate">The aggregate.</param> /// <param name="field">The field to sort by.</param> /// <returns> /// The fluent aggregate interface. /// </returns> public static IOrderedAggregateFluent <TResult> ThenByDescending <TResult>(this IOrderedAggregateFluent <TResult> aggregate, Expression <Func <TResult, object> > field) { Ensure.IsNotNull(aggregate, nameof(aggregate)); return(aggregate.ThenBy(Builders <TResult> .Sort.Descending(field))); }
/// <summary> /// Modifies the current sort stage by appending a descending field specification to it. /// </summary> /// <typeparam name="TDocument">The type of the document.</typeparam> /// <typeparam name="TResult">The type of the result.</typeparam> /// <param name="source">The source.</param> /// <param name="field">The field to sort by.</param> /// <returns>The fluent aggregate interface.</returns> public static IOrderedAggregateFluent <TDocument, TResult> ThenByDescending <TDocument, TResult>(this IOrderedAggregateFluent <TDocument, TResult> source, Expression <Func <TResult, object> > field) { Ensure.IsNotNull(source, "source"); Ensure.IsNotNull(field, "field"); var helper = new BsonSerializationInfoHelper(); helper.RegisterExpressionSerializer(field.Parameters[0], source.Collection.Settings.SerializerRegistry.GetSerializer <TResult>()); var sortDocument = new SortByBuilder <TResult>(helper).Descending(field).ToBsonDocument(); // this looks sketchy, but if we get here and this isn't true, then // someone is being a bad citizen. var currentSortStage = (BsonDocument)source.Pipeline.Last(); currentSortStage["$sort"].AsBsonDocument.AddRange(sortDocument); return(source); }